diff options
author | haitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-21 04:51:26 +0000 |
---|---|---|
committer | haitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-21 04:51:26 +0000 |
commit | 415c0108dcc2db461cf46a6692a27fbf0c36ded8 (patch) | |
tree | ff9c1e1ab3e395758059ba9755735a696eeeb76c /sync/internal_api/public | |
parent | b59dc438a7417bbe89f1c8e88a655e737283392f (diff) | |
download | chromium_src-415c0108dcc2db461cf46a6692a27fbf0c36ded8.zip chromium_src-415c0108dcc2db461cf46a6692a27fbf0c36ded8.tar.gz chromium_src-415c0108dcc2db461cf46a6692a27fbf0c36ded8.tar.bz2 |
Null ModelSafeWorker's working_loop_ if loop is destructed and synchronize access to workiing_loop_. Otherwise ModelSafeWorker could try to unregister for dead loop.
BUG=274729
Review URL: https://chromiumcodereview.appspot.com/22985008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@218648 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync/internal_api/public')
-rw-r--r-- | sync/internal_api/public/engine/model_safe_worker.cc | 32 | ||||
-rw-r--r-- | sync/internal_api/public/engine/model_safe_worker.h | 1 |
2 files changed, 25 insertions, 8 deletions
diff --git a/sync/internal_api/public/engine/model_safe_worker.cc b/sync/internal_api/public/engine/model_safe_worker.cc index 7179ed5..5c91715 100644 --- a/sync/internal_api/public/engine/model_safe_worker.cc +++ b/sync/internal_api/public/engine/model_safe_worker.cc @@ -134,11 +134,17 @@ void ModelSafeWorker::WillDestroyCurrentMessageLoop() { << " worker stops on destruction of its working thread."; } + { + base::AutoLock l(working_loop_lock_); + working_loop_ = NULL; + } + if (observer_) observer_->OnWorkerLoopDestroyed(GetModelSafeGroup()); } void ModelSafeWorker::SetWorkingLoopToCurrent() { + base::AutoLock l(working_loop_lock_); DCHECK(!working_loop_); working_loop_ = base::MessageLoop::current(); working_loop_set_wait_.Signal(); @@ -150,19 +156,29 @@ void ModelSafeWorker::UnregisterForLoopDestruction( // loop. working_loop_set_wait_.Wait(); - // Should be called on sync loop. - DCHECK_NE(base::MessageLoop::current(), working_loop_); - DCHECK(working_loop_); - working_loop_->PostTask( - FROM_HERE, - base::Bind(&ModelSafeWorker::UnregisterForLoopDestructionAsync, - this, unregister_done_callback)); + { + 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)); + } + } } void ModelSafeWorker::UnregisterForLoopDestructionAsync( base::Callback<void(ModelSafeGroup)> unregister_done_callback) { + { + base::AutoLock l(working_loop_lock_); + if (!working_loop_) + return; + DCHECK_EQ(base::MessageLoop::current(), working_loop_); + } + DCHECK(stopped_); - DCHECK_EQ(base::MessageLoop::current(), working_loop_); base::MessageLoop::current()->RemoveDestructionObserver(this); unregister_done_callback.Run(GetModelSafeGroup()); } diff --git a/sync/internal_api/public/engine/model_safe_worker.h b/sync/internal_api/public/engine/model_safe_worker.h index f6b7ea6..0f41594 100644 --- a/sync/internal_api/public/engine/model_safe_worker.h +++ b/sync/internal_api/public/engine/model_safe_worker.h @@ -132,6 +132,7 @@ class SYNC_EXPORT ModelSafeWorker // Remember working loop for posting task to unregister destruction // observation from sync thread when shutting down sync. + base::Lock working_loop_lock_; base::MessageLoop* working_loop_; base::WaitableEvent working_loop_set_wait_; }; |