1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_
6 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/synchronization/lock.h"
15 #include "base/threading/thread.h"
16 #include "sync/internal_api/public/base/model_type.h"
17 #include "sync/internal_api/public/engine/model_safe_worker.h"
18 #include "sync/internal_api/public/sync_manager.h"
30 namespace sync_driver
{
31 class ChangeProcessor
;
34 namespace browser_sync
{
38 // A class that keep track of the workers, change processors, and
39 // routing info for the enabled sync types, and also routes change
40 // events to the right processors.
41 class SyncBackendRegistrar
: public syncer::SyncManager::ChangeDelegate
,
42 public syncer::WorkerLoopDestructionObserver
{
44 // |name| is used for debugging. Does not take ownership of |profile| or
45 // |sync_loop|. Must be created on the UI thread.
46 SyncBackendRegistrar(const std::string
& name
,
48 scoped_ptr
<base::Thread
> sync_thread
);
50 // SyncBackendRegistrar must be destroyed as follows:
52 // 1) On the UI thread, call RequestWorkerStopOnUIThread().
53 // 2) UI posts task to shut down syncer on sync thread.
54 // 3) If sync is disabled, call ReleaseSyncThread() on the UI thread.
55 // 3) UI posts SyncBackendRegistrar::ShutDown() on sync thread to
56 // unregister workers from observing destruction of their working loops.
57 // 4) Workers notify registrar when unregistration finishes or working
58 // loops are destroyed. Registrar destroys itself on last worker
59 // notification. Sync thread will be stopped if ownership was not
61 ~SyncBackendRegistrar() override
;
63 // Informs the SyncBackendRegistrar of the currently enabled set of types.
64 // These types will be placed in the passive group. This function should be
65 // called exactly once during startup.
66 void SetInitialTypes(syncer::ModelTypeSet initial_types
);
68 // Returns whether or not we are currently syncing encryption keys.
69 // Must be called on the UI thread.
70 bool IsNigoriEnabled() const;
72 // Removes all types in |types_to_remove| from the routing info and
73 // adds all the types in |types_to_add| to the routing info that are
74 // not already there (initially put in the passive group).
75 // |types_to_remove| and |types_to_add| must be disjoint. Returns
76 // the set of newly-added types. Must be called on the UI thread.
77 syncer::ModelTypeSet
ConfigureDataTypes(
78 syncer::ModelTypeSet types_to_add
,
79 syncer::ModelTypeSet types_to_remove
);
81 // Returns the set of enabled types as of the last configuration. Note that
82 // this might be different from the current types in the routing info due
83 // to DeactiveDataType being called separately from ConfigureDataTypes.
84 syncer::ModelTypeSet
GetLastConfiguredTypes() const;
86 // Must be called from the UI thread. (See destructor comment.)
87 void RequestWorkerStopOnUIThread();
89 // Activates the given data type (which should belong to the given
90 // group) and starts the given change processor. Must be called
91 // from |group|'s native thread.
92 void ActivateDataType(syncer::ModelType type
,
93 syncer::ModelSafeGroup group
,
94 sync_driver::ChangeProcessor
* change_processor
,
95 syncer::UserShare
* user_share
);
97 // Deactivates the given type if necessary. Must be called from the
98 // UI thread and not |type|'s native thread. Yes, this is
99 // surprising: see http://crbug.com/92804.
100 void DeactivateDataType(syncer::ModelType type
);
102 // Returns true only between calls to ActivateDataType(type, ...)
103 // and DeactivateDataType(type). Used only by tests.
104 bool IsTypeActivatedForTest(syncer::ModelType type
) const;
106 // SyncManager::ChangeDelegate implementation. May be called from
108 void OnChangesApplied(
109 syncer::ModelType model_type
,
111 const syncer::BaseTransaction
* trans
,
112 const syncer::ImmutableChangeRecordList
& changes
) override
;
113 void OnChangesComplete(syncer::ModelType model_type
) override
;
115 void GetWorkers(std::vector
<scoped_refptr
<syncer::ModelSafeWorker
> >* out
);
116 void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo
* out
);
118 // syncer::WorkerLoopDestructionObserver implementation.
119 void OnWorkerLoopDestroyed(syncer::ModelSafeGroup group
) override
;
121 // Release ownership of |sync_thread_|. Called when sync is disabled.
122 scoped_ptr
<base::Thread
> ReleaseSyncThread();
124 // Unregister workers from loop destruction observation.
127 base::Thread
* sync_thread();
130 typedef std::map
<syncer::ModelSafeGroup
,
131 scoped_refptr
<syncer::ModelSafeWorker
> > WorkerMap
;
132 typedef std::map
<syncer::ModelType
, sync_driver::ChangeProcessor
*>
135 // Callback after workers unregister from observing destruction of their
137 void OnWorkerUnregistrationDone(syncer::ModelSafeGroup group
);
139 void RemoveWorker(syncer::ModelSafeGroup group
);
141 // Returns the change processor for the given model, or NULL if none
142 // exists. Must be called from |group|'s native thread.
143 sync_driver::ChangeProcessor
* GetProcessor(syncer::ModelType type
) const;
145 // Must be called with |lock_| held. Simply returns the change
146 // processor for the given type, if it exists. May be called from
148 sync_driver::ChangeProcessor
* GetProcessorUnsafe(
149 syncer::ModelType type
) const;
151 // Return true if |model_type| lives on the current thread. Must be
152 // called with |lock_| held. May be called on any thread.
153 bool IsCurrentThreadSafeForModel(
154 syncer::ModelType model_type
) const;
156 // Name used for debugging.
157 const std::string name_
;
159 Profile
* const profile_
;
161 // Protects all variables below.
162 mutable base::Lock lock_
;
164 // We maintain ownership of all workers. In some cases, we need to
165 // ensure shutdown occurs in an expected sequence by Stop()ing
166 // certain workers. They are guaranteed to be valid because we only
167 // destroy elements of |workers_| after the syncapi has been
168 // destroyed. Unless a worker is no longer needed because all types
169 // that get routed to it have been disabled (from syncing). In that
170 // case, we'll destroy on demand *after* routing any dependent types
171 // to syncer::GROUP_PASSIVE, so that the syncapi doesn't call into garbage.
172 // If a key is present, it means at least one ModelType that routes
173 // to that model safe group is being synced.
175 syncer::ModelSafeRoutingInfo routing_info_
;
177 // The change processors that handle the different data types.
178 ProcessorMap processors_
;
180 // The types that were enabled as of the last configuration. Updated on each
181 // call to ConfigureDataTypes as well as SetInitialTypes.
182 syncer::ModelTypeSet last_configured_types_
;
184 // Parks stopped workers because they may still be referenced by syncer.
185 std::vector
<scoped_refptr
<syncer::ModelSafeWorker
> > stopped_workers_
;
187 // Declare |sync_thread_| at the end so that it will be destroyed before
188 // objects above because tasks on sync thread depend on those objects,
189 // e.g. Shutdown() depends on |lock_|, SyncManager::Init() depends on
191 scoped_ptr
<base::Thread
> sync_thread_
;
193 DISALLOW_COPY_AND_ASSIGN(SyncBackendRegistrar
);
196 } // namespace browser_sync
198 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_