| Index: sync/internal_api/public/engine/model_safe_worker.cc
|
| diff --git a/sync/internal_api/public/engine/model_safe_worker.cc b/sync/internal_api/public/engine/model_safe_worker.cc
|
| index d7bf906ef9f007feec43925789b22a3367a3e15c..3e2096a9423d6f79e6cb1f961347ea1788a8d28f 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
|
|
|