Home | History | Annotate | Download | only in engine
      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:
     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:
     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