summaryrefslogtreecommitdiffstats
path: root/sync/internal_api/public
diff options
context:
space:
mode:
authorhaitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-21 04:51:26 +0000
committerhaitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-21 04:51:26 +0000
commit415c0108dcc2db461cf46a6692a27fbf0c36ded8 (patch)
treeff9c1e1ab3e395758059ba9755735a696eeeb76c /sync/internal_api/public
parentb59dc438a7417bbe89f1c8e88a655e737283392f (diff)
downloadchromium_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.cc32
-rw-r--r--sync/internal_api/public/engine/model_safe_worker.h1
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_;
};