1 // Copyright (c) 2011 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_ENGINE_MODEL_SAFE_WORKER_H_ 6 #define CHROME_BROWSER_SYNC_ENGINE_MODEL_SAFE_WORKER_H_ 7 #pragma once 8 9 #include <map> 10 #include <string> 11 #include <vector> 12 13 #include "base/callback.h" 14 #include "base/memory/ref_counted.h" 15 #include "chrome/browser/sync/syncable/model_type.h" 16 17 namespace browser_sync { 18 19 enum ModelSafeGroup { 20 GROUP_PASSIVE = 0, // Models that are just "passively" being synced; e.g. 21 // changes to these models don't need to be pushed to a 22 // native model. 23 GROUP_UI, // Models that live on UI thread and are being synced. 24 GROUP_DB, // Models that live on DB thread and are being synced. 25 GROUP_HISTORY, // Models that live on history thread and are being 26 // synced. 27 GROUP_PASSWORD, // Models that live on the password thread and are 28 // being synced. On windows and linux, this runs on the 29 // DB thread. 30 MODEL_SAFE_GROUP_COUNT, 31 }; 32 33 std::string ModelSafeGroupToString(ModelSafeGroup group); 34 35 // The Syncer uses a ModelSafeWorker for all tasks that could potentially 36 // modify syncable entries (e.g under a WriteTransaction). The ModelSafeWorker 37 // only knows how to do one thing, and that is take some work (in a fully 38 // pre-bound callback) and have it performed (as in Run()) from a thread which 39 // is guaranteed to be "model-safe", where "safe" refers to not allowing us to 40 // cause an embedding application model to fall out of sync with the 41 // syncable::Directory due to a race. 42 class ModelSafeWorker : public base::RefCountedThreadSafe<ModelSafeWorker> { 43 public: 44 ModelSafeWorker(); 45 virtual ~ModelSafeWorker(); 46 47 // Any time the Syncer performs model modifications (e.g employing a 48 // WriteTransaction), it should be done by this method to ensure it is done 49 // from a model-safe thread. 50 virtual void DoWorkAndWaitUntilDone(Callback0::Type* work); 51 52 virtual ModelSafeGroup GetModelSafeGroup(); 53 54 // Check the current thread and see if it's the thread associated with 55 // this worker. If this returns true, then it should be safe to operate 56 // on models that are in this worker's group. If this returns false, 57 // such work should not be attempted. 58 virtual bool CurrentThreadIsWorkThread(); 59 60 private: 61 friend class base::RefCountedThreadSafe<ModelSafeWorker>; 62 63 DISALLOW_COPY_AND_ASSIGN(ModelSafeWorker); 64 }; 65 66 // A map that details which ModelSafeGroup each syncable::ModelType 67 // belongs to. Routing info can change in response to the user enabling / 68 // disabling sync for certain types, as well as model association completions. 69 typedef std::map<syncable::ModelType, ModelSafeGroup> 70 ModelSafeRoutingInfo; 71 72 ModelSafeGroup GetGroupForModelType(const syncable::ModelType type, 73 const ModelSafeRoutingInfo& routes); 74 75 // Maintain the up-to-date state regarding which ModelSafeWorkers exist and 76 // which types get routed to which worker. When a sync session begins, it will 77 // snapshot the state at that instant, and will use that for the entire 78 // session. This means if a model becomes synced (or unsynced) by the user 79 // during a sync session, that session will complete and be unaware of this 80 // change -- it will only get picked up for the next session. 81 // TODO(tim): That's really the only way I can make sense of it in the Syncer 82 // HOWEVER, it is awkward for running ModelAssociation. We need to make sure 83 // we don't run such a thing until an active session wraps up. 84 class ModelSafeWorkerRegistrar { 85 public: ModelSafeWorkerRegistrar()86 ModelSafeWorkerRegistrar() { } 87 // Get the current list of active ModelSafeWorkers. Should be threadsafe. 88 virtual void GetWorkers(std::vector<ModelSafeWorker*>* out) = 0; 89 90 // Get the current routing information for all enabled model types. 91 // If a model type is not enabled (that is, if the syncer should not 92 // be trying to sync it), it is not in this map. 93 virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out) = 0; 94 protected: ~ModelSafeWorkerRegistrar()95 virtual ~ModelSafeWorkerRegistrar() {} 96 private: 97 DISALLOW_COPY_AND_ASSIGN(ModelSafeWorkerRegistrar); 98 }; 99 100 } // namespace browser_sync 101 102 #endif // CHROME_BROWSER_SYNC_ENGINE_MODEL_SAFE_WORKER_H_ 103