• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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