- add sources.
[platform/framework/web/crosswalk.git] / src / sync / internal_api / public / engine / model_safe_worker.h
1 // Copyright 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 SYNC_INTERNAL_API_PUBLIC_ENGINE_MODEL_SAFE_WORKER_H_
6 #define SYNC_INTERNAL_API_PUBLIC_ENGINE_MODEL_SAFE_WORKER_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
11
12 #include "base/callback.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/synchronization/lock.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "sync/base/sync_export.h"
18 #include "sync/internal_api/public/base/model_type.h"
19 #include "sync/internal_api/public/util/syncer_error.h"
20
21 namespace base {
22 class DictionaryValue;
23 }  // namespace
24
25 namespace syncer {
26
27 // TODO(akalin): Move the non-exported functions in this file to a
28 // private header.
29
30 typedef base::Callback<enum SyncerError(void)> WorkCallback;
31
32 enum ModelSafeGroup {
33   GROUP_PASSIVE = 0,   // Models that are just "passively" being synced; e.g.
34                        // changes to these models don't need to be pushed to a
35                        // native model.
36   GROUP_UI,            // Models that live on UI thread and are being synced.
37   GROUP_DB,            // Models that live on DB thread and are being synced.
38   GROUP_FILE,          // Models that live on FILE thread and are being synced.
39   GROUP_HISTORY,       // Models that live on history thread and are being
40                        // synced.
41   GROUP_PASSWORD,      // Models that live on the password thread and are
42                        // being synced.  On windows and linux, this runs on the
43                        // DB thread.
44   MODEL_SAFE_GROUP_COUNT,
45 };
46
47 SYNC_EXPORT std::string ModelSafeGroupToString(ModelSafeGroup group);
48
49 // WorkerLoopDestructionObserver is notified when the thread where it works
50 // is going to be destroyed.
51 class WorkerLoopDestructionObserver {
52  public:
53   virtual void OnWorkerLoopDestroyed(ModelSafeGroup group) = 0;
54 };
55
56 // The Syncer uses a ModelSafeWorker for all tasks that could potentially
57 // modify syncable entries (e.g under a WriteTransaction). The ModelSafeWorker
58 // only knows how to do one thing, and that is take some work (in a fully
59 // pre-bound callback) and have it performed (as in Run()) from a thread which
60 // is guaranteed to be "model-safe", where "safe" refers to not allowing us to
61 // cause an embedding application model to fall out of sync with the
62 // syncable::Directory due to a race. Each ModelSafeWorker is affiliated with
63 // a thread and does actual work on that thread. On the destruction of that
64 // thread, the affiliated worker is effectively disabled to do more
65 // work and will notify its observer.
66 class SYNC_EXPORT ModelSafeWorker
67     : public base::RefCountedThreadSafe<ModelSafeWorker>,
68       public base::MessageLoop::DestructionObserver {
69  public:
70   // Subclass should implement to observe destruction of the loop where
71   // it actually does work. Called on UI thread immediately after worker is
72   // created.
73   virtual void RegisterForLoopDestruction() = 0;
74
75   // Called on sync loop from SyncBackendRegistrar::ShutDown(). Post task to
76   // working loop to stop observing loop destruction and invoke
77   // |unregister_done_callback|.
78   virtual void UnregisterForLoopDestruction(
79       base::Callback<void(ModelSafeGroup)> unregister_done_callback);
80
81   // If not stopped, call DoWorkAndWaitUntilDoneImpl() to do work. Otherwise
82   // return CANNOT_DO_WORK.
83   SyncerError DoWorkAndWaitUntilDone(const WorkCallback& work);
84
85   // Soft stop worker by setting stopped_ flag. Called when sync is disabled
86   // or browser is shutting down. Called on UI loop.
87   virtual void RequestStop();
88
89   virtual ModelSafeGroup GetModelSafeGroup() = 0;
90
91   // MessageLoop::DestructionObserver implementation.
92   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
93
94  protected:
95   friend class base::RefCountedThreadSafe<ModelSafeWorker>;
96
97   explicit ModelSafeWorker(WorkerLoopDestructionObserver* observer);
98   virtual ~ModelSafeWorker();
99
100   // Any time the Syncer performs model modifications (e.g employing a
101   // WriteTransaction), it should be done by this method to ensure it is done
102   // from a model-safe thread.
103   virtual SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) = 0;
104
105   base::WaitableEvent* work_done_or_stopped() {
106     return &work_done_or_stopped_;
107   }
108
109   // Return true if the worker was stopped. Thread safe.
110   bool IsStopped();
111
112   // Subclass should call this in RegisterForLoopDestruction() from the loop
113   // where work is done.
114   void SetWorkingLoopToCurrent();
115
116  private:
117   void UnregisterForLoopDestructionAsync(
118       base::Callback<void(ModelSafeGroup)> unregister_done_callback);
119
120   // Whether the worker should/can do more work. Set when sync is disabled or
121   // when the worker's working thread is to be destroyed.
122   base::Lock stopped_lock_;
123   bool stopped_;
124
125   // Signal set when work on native thread is finished or when native thread
126   // is to be destroyed so no more work can be done.
127   base::WaitableEvent work_done_or_stopped_;
128
129   // Notified when working thread of the worker is to be destroyed.
130   WorkerLoopDestructionObserver* observer_;
131
132   // Remember working loop for posting task to unregister destruction
133   // observation from sync thread when shutting down sync.
134   base::Lock working_loop_lock_;
135   base::MessageLoop* working_loop_;
136   base::WaitableEvent working_loop_set_wait_;
137 };
138
139 // A map that details which ModelSafeGroup each ModelType
140 // belongs to.  Routing info can change in response to the user enabling /
141 // disabling sync for certain types, as well as model association completions.
142 typedef std::map<ModelType, ModelSafeGroup> ModelSafeRoutingInfo;
143
144 // Caller takes ownership of return value.
145 SYNC_EXPORT_PRIVATE base::DictionaryValue* ModelSafeRoutingInfoToValue(
146     const ModelSafeRoutingInfo& routing_info);
147
148 SYNC_EXPORT std::string ModelSafeRoutingInfoToString(
149     const ModelSafeRoutingInfo& routing_info);
150
151 SYNC_EXPORT ModelTypeSet GetRoutingInfoTypes(
152     const ModelSafeRoutingInfo& routing_info);
153
154 SYNC_EXPORT ModelSafeGroup GetGroupForModelType(
155     const ModelType type,
156     const ModelSafeRoutingInfo& routes);
157
158 }  // namespace syncer
159
160 #endif  // SYNC_INTERNAL_API_PUBLIC_ENGINE_MODEL_SAFE_WORKER_H_