summaryrefslogtreecommitdiffstats
path: root/sync/internal_api/public/engine/model_safe_worker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sync/internal_api/public/engine/model_safe_worker.cc')
-rw-r--r--sync/internal_api/public/engine/model_safe_worker.cc52
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