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. 4 5 #ifndef CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_ 6 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_ 7 8 #include <map> 9 #include <vector> 10 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" 19 20 class Profile; 21 22 namespace base { 23 class MessageLoop; 24 } 25 26 namespace syncer { 27 struct UserShare; 28 } // namespace syncer 29 30 namespace sync_driver { 31 class ChangeProcessor; 32 } 33 34 namespace browser_sync { 35 36 class UIModelWorker; 37 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 { 43 public: 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, 47 Profile* profile, 48 scoped_ptr<base::Thread> sync_thread); 49 50 // SyncBackendRegistrar must be destroyed as follows: 51 // 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 60 // released. 61 virtual ~SyncBackendRegistrar(); 62 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); 67 68 // Returns whether or not we are currently syncing encryption keys. 69 // Must be called on the UI thread. 70 bool IsNigoriEnabled() const; 71 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); 80 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; 85 86 // Must be called from the UI thread. (See destructor comment.) 87 void RequestWorkerStopOnUIThread(); 88 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); 96 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); 101 102 // Returns true only between calls to ActivateDataType(type, ...) 103 // and DeactivateDataType(type). Used only by tests. 104 bool IsTypeActivatedForTest(syncer::ModelType type) const; 105 106 // SyncManager::ChangeDelegate implementation. May be called from 107 // any thread. 108 virtual void OnChangesApplied( 109 syncer::ModelType model_type, 110 int64 model_version, 111 const syncer::BaseTransaction* trans, 112 const syncer::ImmutableChangeRecordList& changes) OVERRIDE; 113 virtual void OnChangesComplete(syncer::ModelType model_type) OVERRIDE; 114 115 void GetWorkers(std::vector<scoped_refptr<syncer::ModelSafeWorker> >* out); 116 void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out); 117 118 // syncer::WorkerLoopDestructionObserver implementation. 119 virtual void OnWorkerLoopDestroyed(syncer::ModelSafeGroup group) OVERRIDE; 120 121 // Release ownership of |sync_thread_|. Called when sync is disabled. 122 scoped_ptr<base::Thread> ReleaseSyncThread(); 123 124 // Unregister workers from loop destruction observation. 125 void Shutdown(); 126 127 base::Thread* sync_thread(); 128 129 private: 130 typedef std::map<syncer::ModelSafeGroup, 131 scoped_refptr<syncer::ModelSafeWorker> > WorkerMap; 132 typedef std::map<syncer::ModelType, sync_driver::ChangeProcessor*> 133 ProcessorMap; 134 135 // Callback after workers unregister from observing destruction of their 136 // working loops. 137 void OnWorkerUnregistrationDone(syncer::ModelSafeGroup group); 138 139 void RemoveWorker(syncer::ModelSafeGroup group); 140 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; 144 145 // Must be called with |lock_| held. Simply returns the change 146 // processor for the given type, if it exists. May be called from 147 // any thread. 148 sync_driver::ChangeProcessor* GetProcessorUnsafe( 149 syncer::ModelType type) const; 150 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; 155 156 // Name used for debugging. 157 const std::string name_; 158 159 Profile* const profile_; 160 161 // Protects all variables below. 162 mutable base::Lock lock_; 163 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. 174 WorkerMap workers_; 175 syncer::ModelSafeRoutingInfo routing_info_; 176 177 // The change processors that handle the different data types. 178 ProcessorMap processors_; 179 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_; 183 184 // Parks stopped workers because they may still be referenced by syncer. 185 std::vector<scoped_refptr<syncer::ModelSafeWorker> > stopped_workers_; 186 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 190 // workers, etc. 191 scoped_ptr<base::Thread> sync_thread_; 192 193 DISALLOW_COPY_AND_ASSIGN(SyncBackendRegistrar); 194 }; 195 196 } // namespace browser_sync 197 198 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_REGISTRAR_H_ 199