diff options
Diffstat (limited to 'sync/internal_api/public/engine/model_safe_worker.h')
-rw-r--r-- | sync/internal_api/public/engine/model_safe_worker.h | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/sync/internal_api/public/engine/model_safe_worker.h b/sync/internal_api/public/engine/model_safe_worker.h index fbec6b1..94925df 100644 --- a/sync/internal_api/public/engine/model_safe_worker.h +++ b/sync/internal_api/public/engine/model_safe_worker.h @@ -11,6 +11,9 @@ #include "base/callback.h" #include "base/memory/ref_counted.h" +#include "base/message_loop.h" +#include "base/synchronization/lock.h" +#include "base/synchronization/waitable_event.h" #include "sync/base/sync_export.h" #include "sync/internal_api/public/base/model_type.h" #include "sync/internal_api/public/base/model_type_invalidation_map.h" @@ -44,28 +47,74 @@ enum ModelSafeGroup { SYNC_EXPORT std::string ModelSafeGroupToString(ModelSafeGroup group); +// WorkerLoopDestructionObserver is notified when the thread where it works +// is going to be destroyed. +class WorkerLoopDestructionObserver { + public: + virtual void OnWorkerLoopDestroyed(ModelSafeGroup group) = 0; +}; + // The Syncer uses a ModelSafeWorker for all tasks that could potentially // modify syncable entries (e.g under a WriteTransaction). The ModelSafeWorker // only knows how to do one thing, and that is take some work (in a fully // pre-bound callback) and have it performed (as in Run()) from a thread which // is guaranteed to be "model-safe", where "safe" refers to not allowing us to // cause an embedding application model to fall out of sync with the -// syncable::Directory due to a race. +// syncable::Directory due to a race. Each ModelSafeWorker is affiliated with +// a thread and does actual work on that thread. On the destruction of that +// thread, the affiliated worker is effectively disabled to do more +// work and will notify its observer. class SYNC_EXPORT ModelSafeWorker - : public base::RefCountedThreadSafe<ModelSafeWorker> { + : public base::RefCountedThreadSafe<ModelSafeWorker>, + public MessageLoop::DestructionObserver { public: - // Any time the Syncer performs model modifications (e.g employing a - // WriteTransaction), it should be done by this method to ensure it is done - // from a model-safe thread. - virtual SyncerError DoWorkAndWaitUntilDone(const WorkCallback& work) = 0; + // Subclass should implement to observe destruction of the loop where + // it actually does work. + virtual void RegisterForLoopDestruction() = 0; + + // If not stopped, call DoWorkAndWaitUntilDoneImpl() to do work. Otherwise + // return CANNOT_DO_WORK. + SyncerError DoWorkAndWaitUntilDone(const WorkCallback& work); + + // Soft stop worker by setting stopped_ flag. Called when sync is disabled + // or browser is shutting down. + void RequestStop(); virtual ModelSafeGroup GetModelSafeGroup() = 0; + // MessageLoop::DestructionObserver implementation. + virtual void WillDestroyCurrentMessageLoop() OVERRIDE; + protected: + friend class base::RefCountedThreadSafe<ModelSafeWorker>; + + explicit ModelSafeWorker(WorkerLoopDestructionObserver* observer); virtual ~ModelSafeWorker(); + // Any time the Syncer performs model modifications (e.g employing a + // WriteTransaction), it should be done by this method to ensure it is done + // from a model-safe thread. + virtual SyncerError DoWorkAndWaitUntilDoneImpl(const WorkCallback& work) = 0; + + base::WaitableEvent* work_done_or_stopped() { + return &work_done_or_stopped_; + } + + // Return true if the worker was stopped. Thread safe. + bool IsStopped(); + private: - friend class base::RefCountedThreadSafe<ModelSafeWorker>; + // Whether the worker should/can do more work. Set when sync is disabled or + // when the worker's working thread is to be destroyed. + base::Lock stopped_lock_; + bool stopped_; + + // Signal set when work on native thread is finished or when native thread + // is to be destroyed so no more work can be done. + base::WaitableEvent work_done_or_stopped_; + + // Notified when working thread of the worker is to be destroyed. + WorkerLoopDestructionObserver* observer_; }; // A map that details which ModelSafeGroup each ModelType |