Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: components/sync/driver/glue/sync_backend_registrar.h

Issue 2471183003: Do not observe MessageLoop destruction from ModelSafeWorker. (Closed)
Patch Set: CR maxbogue #23 Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ 5 #ifndef COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_
6 #define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ 6 #define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <map> 10 #include <map>
11 #include <memory> 11 #include <memory>
12 #include <string> 12 #include <string>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/compiler_specific.h"
16 #include "base/macros.h" 15 #include "base/macros.h"
17 #include "base/memory/ref_counted.h" 16 #include "base/memory/ref_counted.h"
18 #include "base/synchronization/lock.h" 17 #include "base/synchronization/lock.h"
19 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
20 #include "components/sync/base/model_type.h" 19 #include "components/sync/base/model_type.h"
21 #include "components/sync/engine/model_safe_worker.h" 20 #include "components/sync/engine/model_safe_worker.h"
22 #include "components/sync/engine/sync_manager.h" 21 #include "components/sync/engine/sync_manager.h"
23 22
24 class Profile;
25
26 namespace base {
27 class MessageLoop;
28 }
29
30 namespace syncer { 23 namespace syncer {
31 24
32 class ChangeProcessor; 25 class ChangeProcessor;
33 class SyncClient; 26 class SyncClient;
34 class UIModelWorker;
35 struct UserShare; 27 struct UserShare;
36 28
37 // A class that keep track of the workers, change processors, and 29 // A class that keep track of the workers, change processors, and
38 // routing info for the enabled sync types, and also routes change 30 // routing info for the enabled sync types, and also routes change
39 // events to the right processors. 31 // events to the right processors.
40 class SyncBackendRegistrar : public SyncManager::ChangeDelegate, 32 class SyncBackendRegistrar : public SyncManager::ChangeDelegate {
41 public WorkerLoopDestructionObserver {
42 public: 33 public:
43 // |name| is used for debugging. Does not take ownership of |profile|. 34 // |name| is used for debugging. Must be created on the UI thread.
44 // Must be created on the UI thread.
45 SyncBackendRegistrar( 35 SyncBackendRegistrar(
46 const std::string& name, 36 const std::string& name,
47 SyncClient* sync_client, 37 SyncClient* sync_client,
48 std::unique_ptr<base::Thread> sync_thread, 38 std::unique_ptr<base::Thread> sync_thread,
49 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, 39 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
50 const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, 40 const scoped_refptr<base::SingleThreadTaskRunner>& db_thread,
51 const scoped_refptr<base::SingleThreadTaskRunner>& file_thread); 41 const scoped_refptr<base::SingleThreadTaskRunner>& file_thread);
52 42
53 // SyncBackendRegistrar must be destroyed as follows: 43 // A SyncBackendRegistrar is owned by a SyncBackendHostImpl. It is destroyed
44 // by SyncBackendHostImpl::Shutdown() which performs the following operations
45 // on the UI thread:
54 // 46 //
55 // 1) On the UI thread, call RequestWorkerStopOnUIThread(). 47 // 1) Call SyncBackendRegistrar::RequestWorkerStopOnUIThread().
56 // 2) UI posts task to shut down syncer on sync thread. 48 // 2) Post a SyncBackendHostCore::DoShutdown() task to the sync thread. This
57 // 3) If sync is disabled, call ReleaseSyncThread() on the UI thread. 49 // task destroys SyncManager which holds a SyncBackendRegistrar pointer.
58 // 3) UI posts SyncBackendRegistrar::ShutDown() on sync thread to 50 // 3) Take ownership of the sync thread.
59 // unregister workers from observing destruction of their working loops. 51 // 4) Post a task to delete the SyncBackendRegistrar on the sync thread.
60 // 4) Workers notify registrar when unregistration finishes or working 52 // When this task runs, there are no remaining pointers to the
61 // loops are destroyed. Registrar destroys itself on last worker 53 // SyncBackendRegistrar.
62 // notification. Sync thread will be stopped if ownership was not
63 // released.
64 ~SyncBackendRegistrar() override; 54 ~SyncBackendRegistrar() override;
65 55
66 // Adds |type| to set of non-blocking types. These types are assigned to 56 // Adds |type| to set of non-blocking types. These types are assigned to
67 // GROUP_NON_BLOCKING model safe group and will be treated differently in 57 // GROUP_NON_BLOCKING model safe group and will be treated differently in
68 // ModelTypeRegistry. Unlike directory types, non-blocking types always stay 58 // ModelTypeRegistry. Unlike directory types, non-blocking types always stay
69 // assigned to GROUP_NON_BLOCKING group. 59 // assigned to GROUP_NON_BLOCKING group.
70 void RegisterNonBlockingType(ModelType type); 60 void RegisterNonBlockingType(ModelType type);
71 61
72 // Informs the SyncBackendRegistrar of the currently enabled set of types. 62 // Informs the SyncBackendRegistrar of the currently enabled set of types.
73 // These types will be placed in the passive group. This function should be 63 // These types will be placed in the passive group. This function should be
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 // any thread. 110 // any thread.
121 void OnChangesApplied(ModelType model_type, 111 void OnChangesApplied(ModelType model_type,
122 int64_t model_version, 112 int64_t model_version,
123 const BaseTransaction* trans, 113 const BaseTransaction* trans,
124 const ImmutableChangeRecordList& changes) override; 114 const ImmutableChangeRecordList& changes) override;
125 void OnChangesComplete(ModelType model_type) override; 115 void OnChangesComplete(ModelType model_type) override;
126 116
127 void GetWorkers(std::vector<scoped_refptr<ModelSafeWorker>>* out); 117 void GetWorkers(std::vector<scoped_refptr<ModelSafeWorker>>* out);
128 void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out); 118 void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out);
129 119
130 // WorkerLoopDestructionObserver implementation.
131 void OnWorkerLoopDestroyed(ModelSafeGroup group) override;
132
133 // Release ownership of |sync_thread_|. Called when sync is disabled. 120 // Release ownership of |sync_thread_|. Called when sync is disabled.
134 std::unique_ptr<base::Thread> ReleaseSyncThread(); 121 std::unique_ptr<base::Thread> ReleaseSyncThread();
135 122
136 // Unregister workers from loop destruction observation.
137 void Shutdown();
138
139 base::Thread* sync_thread(); 123 base::Thread* sync_thread();
140 124
141 private: 125 private:
142 typedef std::map<ModelSafeGroup, scoped_refptr<ModelSafeWorker>> WorkerMap; 126 typedef std::map<ModelSafeGroup, scoped_refptr<ModelSafeWorker>> WorkerMap;
143 typedef std::map<ModelType, ChangeProcessor*> ProcessorMap; 127 typedef std::map<ModelType, ChangeProcessor*> ProcessorMap;
144 128
145 // Add a worker for |group| to the worker map if one can be created. 129 // Add a worker for |group| to the worker map if one can be created.
146 void MaybeAddWorker(ModelSafeGroup group); 130 void MaybeAddWorker(ModelSafeGroup group);
147 131
148 // Callback after workers unregister from observing destruction of their
149 // working loops.
150 void OnWorkerUnregistrationDone(ModelSafeGroup group);
151
152 void RemoveWorker(ModelSafeGroup group);
153
154 // Returns the change processor for the given model, or null if none 132 // Returns the change processor for the given model, or null if none
155 // exists. Must be called from |group|'s native thread. 133 // exists. Must be called from |group|'s native thread.
156 ChangeProcessor* GetProcessor(ModelType type) const; 134 ChangeProcessor* GetProcessor(ModelType type) const;
157 135
158 // Must be called with |lock_| held. Simply returns the change 136 // Must be called with |lock_| held. Simply returns the change
159 // processor for the given type, if it exists. May be called from 137 // processor for the given type, if it exists. May be called from
160 // any thread. 138 // any thread.
161 ChangeProcessor* GetProcessorUnsafe(ModelType type) const; 139 ChangeProcessor* GetProcessorUnsafe(ModelType type) const;
162 140
163 // Return true if |model_type| lives on the current thread. Must be 141 // Return true if |model_type| lives on the current thread. Must be
(...skipping 11 matching lines...) Expand all
175 153
176 // Name used for debugging. 154 // Name used for debugging.
177 const std::string name_; 155 const std::string name_;
178 156
179 // A pointer to the sync client. 157 // A pointer to the sync client.
180 SyncClient* const sync_client_; 158 SyncClient* const sync_client_;
181 159
182 // Protects all variables below. 160 // Protects all variables below.
183 mutable base::Lock lock_; 161 mutable base::Lock lock_;
184 162
185 // We maintain ownership of all workers. In some cases, we need to 163 // Workers created by this SyncBackendRegistrar.
186 // ensure shutdown occurs in an expected sequence by Stop()ing
187 // certain workers. They are guaranteed to be valid because we only
188 // destroy elements of |workers_| after the syncapi has been
189 // destroyed. Unless a worker is no longer needed because all types
190 // that get routed to it have been disabled (from syncing). In that
191 // case, we'll destroy on demand *after* routing any dependent types
192 // to GROUP_PASSIVE, so that the syncapi doesn't call into garbage.
193 // If a key is present, it means at least one ModelType that routes
194 // to that model safe group is being synced.
195 WorkerMap workers_; 164 WorkerMap workers_;
165
196 ModelSafeRoutingInfo routing_info_; 166 ModelSafeRoutingInfo routing_info_;
197 167
198 // The change processors that handle the different data types. 168 // The change processors that handle the different data types.
199 ProcessorMap processors_; 169 ProcessorMap processors_;
200 170
201 // The types that were enabled as of the last configuration. Updated on each 171 // The types that were enabled as of the last configuration. Updated on each
202 // call to ConfigureDataTypes as well as SetInitialTypes. 172 // call to ConfigureDataTypes as well as SetInitialTypes.
203 ModelTypeSet last_configured_types_; 173 ModelTypeSet last_configured_types_;
204 174
205 // Parks stopped workers because they may still be referenced by syncer.
206 std::vector<scoped_refptr<ModelSafeWorker>> stopped_workers_;
207
208 // References to the thread task runners that sync depends on. 175 // References to the thread task runners that sync depends on.
209 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; 176 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_;
210 const scoped_refptr<base::SingleThreadTaskRunner> db_thread_; 177 const scoped_refptr<base::SingleThreadTaskRunner> db_thread_;
211 const scoped_refptr<base::SingleThreadTaskRunner> file_thread_; 178 const scoped_refptr<base::SingleThreadTaskRunner> file_thread_;
212 179
213 // Declare |sync_thread_| at the end so that it will be destroyed before
214 // objects above because tasks on sync thread depend on those objects,
215 // e.g. Shutdown() depends on |lock_|, SyncManager::Init() depends on
216 // workers, etc.
217 std::unique_ptr<base::Thread> sync_thread_; 180 std::unique_ptr<base::Thread> sync_thread_;
218 181
219 // Set of types with non-blocking implementation (as opposed to directory 182 // Set of types with non-blocking implementation (as opposed to directory
220 // based). 183 // based).
221 ModelTypeSet non_blocking_types_; 184 ModelTypeSet non_blocking_types_;
222 185
223 DISALLOW_COPY_AND_ASSIGN(SyncBackendRegistrar); 186 DISALLOW_COPY_AND_ASSIGN(SyncBackendRegistrar);
224 }; 187 };
225 188
226 } // namespace syncer 189 } // namespace syncer
227 190
228 #endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ 191 #endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_
OLDNEW
« no previous file with comments | « components/sync/driver/glue/sync_backend_host_impl_unittest.cc ('k') | components/sync/driver/glue/sync_backend_registrar.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698