diff options
Diffstat (limited to 'sync/internal_api/public/engine/model_safe_worker.cc')
-rw-r--r-- | sync/internal_api/public/engine/model_safe_worker.cc | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/sync/internal_api/public/engine/model_safe_worker.cc b/sync/internal_api/public/engine/model_safe_worker.cc index d7bf906..3e2096a 100644 --- a/sync/internal_api/public/engine/model_safe_worker.cc +++ b/sync/internal_api/public/engine/model_safe_worker.cc @@ -80,6 +80,58 @@ std::string ModelSafeGroupToString(ModelSafeGroup group) { } } +ModelSafeWorker::ModelSafeWorker(WorkerLoopDestructionObserver* observer) + : stopped_(false), + work_done_or_stopped_(false, false), + observer_(observer) {} + ModelSafeWorker::~ModelSafeWorker() {} +void ModelSafeWorker::RequestStop() { + base::AutoLock al(stopped_lock_); + + // Set stop flag but don't signal work_done_or_stopped_ to unblock sync loop + // because the worker may be working and depending on sync command object + // living on sync thread. his prevents any *further* tasks from being posted + // to worker threads (see DoWorkAndWaitUntilDone below), but note that one + // may already be posted. + stopped_ = true; +} + +SyncerError ModelSafeWorker::DoWorkAndWaitUntilDone(const WorkCallback& work) { + { + base::AutoLock al(stopped_lock_); + if (stopped_) + return CANNOT_DO_WORK; + + CHECK(!work_done_or_stopped_.IsSignaled()); + } + + return DoWorkAndWaitUntilDoneImpl(work); +} + +bool ModelSafeWorker::IsStopped() { + base::AutoLock al(stopped_lock_); + return stopped_; +} + +void ModelSafeWorker::WillDestroyCurrentMessageLoop() { + { + base::AutoLock al(stopped_lock_); + stopped_ = true; + + // Must signal to unblock syncer if it's waiting for a posted task to + // finish. At this point, all pending tasks posted to the loop have been + // destroyed (see MessageLoop::~MessageLoop). So syncer will be blocked + // indefinitely without signaling here. + work_done_or_stopped_.Signal(); + + DVLOG(1) << ModelSafeGroupToString(GetModelSafeGroup()) + << " worker stops on destruction of its working thread."; + } + + if (observer_) + observer_->OnWorkerLoopDestroyed(GetModelSafeGroup()); +} + } // namespace syncer |