Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3339)

Unified Diff: sync/internal_api/public/engine/model_safe_worker.cc

Issue 667573007: Revert "Sync: Avoid deadlock in SyncBackendRegistrar / ModelSafeWorker on sync backend shutdown." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 2aea5cf8378b0b9dbc1350410bdea6b19f8fe2a1..eb3fc1f1c3ec286c961e743b23b05e77a7eae358 100644
--- a/sync/internal_api/public/engine/model_safe_worker.cc
+++ b/sync/internal_api/public/engine/model_safe_worker.cc
@@ -75,8 +75,8 @@ ModelSafeWorker::ModelSafeWorker(WorkerLoopDestructionObserver* observer)
: stopped_(false),
work_done_or_stopped_(false, false),
observer_(observer),
- working_loop_(NULL) {
-}
+ working_loop_(NULL),
+ working_loop_set_wait_(true, false) {}
ModelSafeWorker::~ModelSafeWorker() {}
@@ -135,42 +135,26 @@ void ModelSafeWorker::WillDestroyCurrentMessageLoop() {
void ModelSafeWorker::SetWorkingLoopToCurrent() {
base::AutoLock l(working_loop_lock_);
DCHECK(!working_loop_);
-
- if (unregister_done_callback_.is_null()) {
- // Expected case - UnregisterForLoopDestruction hasn't been called yet.
- base::MessageLoop::current()->AddDestructionObserver(this);
- working_loop_ = base::MessageLoop::current();
- } else {
- // Rare case which is possible when the model type thread remains
- // blocked for the entire session and UnregisterForLoopDestruction ends
- // up being called before this method. This method is posted unlike
- // UnregisterForLoopDestruction - that's why they can end up being called
- // out of order.
- // In this case we skip the destruction observer registration
- // and just invoke the callback stored at UnregisterForLoopDestruction.
- DCHECK(stopped_);
- unregister_done_callback_.Run(GetModelSafeGroup());
- }
+ working_loop_ = base::MessageLoop::current();
+ working_loop_set_wait_.Signal();
}
void ModelSafeWorker::UnregisterForLoopDestruction(
base::Callback<void(ModelSafeGroup)> unregister_done_callback) {
- base::AutoLock l(working_loop_lock_);
- if (working_loop_ != NULL) {
- // Normal case - observer registration has been already done.
- // Delegate to the sync thread to do the actual unregistration in
- // UnregisterForLoopDestructionAsync.
- DCHECK_NE(base::MessageLoop::current(), working_loop_);
- working_loop_->PostTask(
- FROM_HERE,
- base::Bind(&ModelSafeWorker::UnregisterForLoopDestructionAsync,
- this,
- unregister_done_callback));
- } else {
- // The working loop is still unknown, probably because the model type
- // thread is blocked. Store the callback to be called from
- // SetWorkingLoopToCurrent.
- unregister_done_callback_ = unregister_done_callback;
+ // Ok to wait until |working_loop_| is set because this is called on sync
+ // loop.
+ working_loop_set_wait_.Wait();
+
+ {
+ base::AutoLock l(working_loop_lock_);
+ if (working_loop_ != NULL) {
+ // Should be called on sync loop.
+ DCHECK_NE(base::MessageLoop::current(), working_loop_);
+ working_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&ModelSafeWorker::UnregisterForLoopDestructionAsync,
+ this, unregister_done_callback));
+ }
}
}
« no previous file with comments | « sync/internal_api/public/engine/model_safe_worker.h ('k') | sync/internal_api/public/engine/passive_model_worker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698