diff options
author | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-21 17:26:53 +0000 |
---|---|---|
committer | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-21 17:26:53 +0000 |
commit | 8d414d1745e35507538834873584874e2e84323b (patch) | |
tree | 95ff6d97a5300ff7abb8afa447a933795fd2d165 | |
parent | 7aa0a96ae010300281e897ac9b8111683fb5672c (diff) | |
download | chromium_src-8d414d1745e35507538834873584874e2e84323b.zip chromium_src-8d414d1745e35507538834873584874e2e84323b.tar.gz chromium_src-8d414d1745e35507538834873584874e2e84323b.tar.bz2 |
Sync: Check that the current thread is a ModelSafeWorker's home thread.
Use this in sync_backend_host.cc to avoid dispatching to a data type
controller except when we're on the DTC's home thread.
BUG=41824
TEST=during manual testing of 2-client sync; this code is never active
during add/deletes and associates/disassociates.
Review URL: http://codereview.chromium.org/1741001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45201 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/sync/engine/mock_model_safe_workers.h | 2 | ||||
-rw-r--r-- | chrome/browser/sync/engine/model_safe_worker.h | 11 | ||||
-rw-r--r-- | chrome/browser/sync/glue/database_model_worker.cc | 4 | ||||
-rw-r--r-- | chrome/browser/sync/glue/database_model_worker.h | 1 | ||||
-rw-r--r-- | chrome/browser/sync/glue/history_model_worker.cc | 5 | ||||
-rw-r--r-- | chrome/browser/sync/glue/history_model_worker.h | 1 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host.cc | 26 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host.h | 3 | ||||
-rw-r--r-- | chrome/browser/sync/glue/ui_model_worker.cc | 4 | ||||
-rw-r--r-- | chrome/browser/sync/glue/ui_model_worker.h | 1 | ||||
-rw-r--r-- | chrome/browser/sync/glue/ui_model_worker_unittest.cc | 2 |
11 files changed, 58 insertions, 2 deletions
diff --git a/chrome/browser/sync/engine/mock_model_safe_workers.h b/chrome/browser/sync/engine/mock_model_safe_workers.h index e776596..13d66aa 100644 --- a/chrome/browser/sync/engine/mock_model_safe_workers.h +++ b/chrome/browser/sync/engine/mock_model_safe_workers.h @@ -12,11 +12,13 @@ namespace browser_sync { class MockUIModelWorker : public ModelSafeWorker { public: virtual ModelSafeGroup GetModelSafeGroup() { return GROUP_UI; } + virtual bool CurrentThreadIsWorkThread() { return true; } }; class MockDBModelWorker : public ModelSafeWorker { public: virtual ModelSafeGroup GetModelSafeGroup() { return GROUP_DB; } + virtual bool CurrentThreadIsWorkThread() { return true; } }; } // namespace browser_sync diff --git a/chrome/browser/sync/engine/model_safe_worker.h b/chrome/browser/sync/engine/model_safe_worker.h index df2edae..7d7461a 100644 --- a/chrome/browser/sync/engine/model_safe_worker.h +++ b/chrome/browser/sync/engine/model_safe_worker.h @@ -49,9 +49,18 @@ class ModelSafeWorker : public base::RefCountedThreadSafe<ModelSafeWorker> { return GROUP_PASSIVE; } + // Check the current thread and see if it's the thread associated with + // this worker. If this returns true, then it should be safe to operate + // on models that are in this worker's group. If this returns false, + // such work should not be attempted. + virtual bool CurrentThreadIsWorkThread() { + // The passive group is not the work thread for any browser model. + return false; + } + private: friend class base::RefCountedThreadSafe<ModelSafeWorker>; - + DISALLOW_COPY_AND_ASSIGN(ModelSafeWorker); }; diff --git a/chrome/browser/sync/glue/database_model_worker.cc b/chrome/browser/sync/glue/database_model_worker.cc index 02516c7..95c49a6 100644 --- a/chrome/browser/sync/glue/database_model_worker.cc +++ b/chrome/browser/sync/glue/database_model_worker.cc @@ -33,4 +33,8 @@ void DatabaseModelWorker::CallDoWorkAndSignalTask(Closure* work, done->Signal(); } +bool DatabaseModelWorker::CurrentThreadIsWorkThread() { + return ChromeThread::CurrentlyOn(ChromeThread::DB); +} + } // namespace browser_sync diff --git a/chrome/browser/sync/glue/database_model_worker.h b/chrome/browser/sync/glue/database_model_worker.h index 64f53ed..fbaf2bd 100644 --- a/chrome/browser/sync/glue/database_model_worker.h +++ b/chrome/browser/sync/glue/database_model_worker.h @@ -21,6 +21,7 @@ class DatabaseModelWorker : public browser_sync::ModelSafeWorker { // ModelSafeWorker implementation. Called on syncapi SyncerThread. void DoWorkAndWaitUntilDone(Closure* work); virtual ModelSafeGroup GetModelSafeGroup() { return GROUP_DB; } + virtual bool CurrentThreadIsWorkThread(); private: void CallDoWorkAndSignalTask(Closure* work, base::WaitableEvent* done); diff --git a/chrome/browser/sync/glue/history_model_worker.cc b/chrome/browser/sync/glue/history_model_worker.cc index cab697c..74b914b 100644 --- a/chrome/browser/sync/glue/history_model_worker.cc +++ b/chrome/browser/sync/glue/history_model_worker.cc @@ -50,4 +50,9 @@ void HistoryModelWorker::DoWorkAndWaitUntilDone(Closure* work) { done.Wait(); } +bool HistoryModelWorker::CurrentThreadIsWorkThread() { + // TODO(ncarter): How to determine this? + return true; +} + } // namespace browser_sync diff --git a/chrome/browser/sync/glue/history_model_worker.h b/chrome/browser/sync/glue/history_model_worker.h index d9fa5ed..6fd65e8 100644 --- a/chrome/browser/sync/glue/history_model_worker.h +++ b/chrome/browser/sync/glue/history_model_worker.h @@ -30,6 +30,7 @@ class HistoryModelWorker : public browser_sync::ModelSafeWorker, // ModelSafeWorker implementation. Called on syncapi SyncerThread. void DoWorkAndWaitUntilDone(Closure* work); virtual ModelSafeGroup GetModelSafeGroup() { return GROUP_HISTORY; } + virtual bool CurrentThreadIsWorkThread(); // CancelableRequestConsumerBase implementation. virtual void OnRequestAdded(CancelableRequestProvider* provider, diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc index 1d49bc6..647dbb1 100644 --- a/chrome/browser/sync/glue/sync_backend_host.cc +++ b/chrome/browser/sync/glue/sync_backend_host.cc @@ -420,6 +420,14 @@ void SyncBackendHost::Core::OnChangesApplied( // association. if (it == host_->processors_.end()) return; + + if (!IsCurrentThreadSafeForModel(model_type)) { + NOTREACHED() << "Changes applied on wrong thread."; + return; + } + + // Now that we're sure we're on the correct thread, we can access the + // ChangeProcessor. ChangeProcessor* processor = it->second; // Ensure the change processor is willing to accept changes. @@ -484,6 +492,24 @@ void SyncBackendHost::Core::HandleInitalizationCompletedOnFrontendLoop() { host_->frontend_->OnBackendInitialized(); } + +bool SyncBackendHost::Core::IsCurrentThreadSafeForModel( + syncable::ModelType model_type) { + AutoLock lock(host_->registrar_lock_); + + browser_sync::ModelSafeRoutingInfo::const_iterator routing_it = + host_->registrar_.routing_info.find(model_type); + if (routing_it == host_->registrar_.routing_info.end()) + return false; + browser_sync::ModelSafeGroup group = routing_it->second; + WorkerMap::const_iterator worker_it = host_->registrar_.workers.find(group); + if (worker_it == host_->registrar_.workers.end()) + return false; + ModelSafeWorker* worker = worker_it->second; + return worker->CurrentThreadIsWorkThread(); +} + + void SyncBackendHost::Core::OnAuthError(const AuthError& auth_error) { // We could be on SyncEngine_AuthWatcherThread. Post to our core loop so // we can modify state. diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h index 574f299..4704f85 100644 --- a/chrome/browser/sync/glue/sync_backend_host.h +++ b/chrome/browser/sync/glue/sync_backend_host.h @@ -343,6 +343,9 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { // frontend thread components. void HandleInitalizationCompletedOnFrontendLoop(); + // Return true if a model lives on the current thread. + bool IsCurrentThreadSafeForModel(syncable::ModelType model_type); + // Our parent SyncBackendHost SyncBackendHost* host_; diff --git a/chrome/browser/sync/glue/ui_model_worker.cc b/chrome/browser/sync/glue/ui_model_worker.cc index 89a9c43..d1a12b6 100644 --- a/chrome/browser/sync/glue/ui_model_worker.cc +++ b/chrome/browser/sync/glue/ui_model_worker.cc @@ -81,6 +81,10 @@ void UIModelWorker::Stop() { state_ = STOPPED; } +bool UIModelWorker::CurrentThreadIsWorkThread() { + return MessageLoop::current() == ui_loop_; +} + void UIModelWorker::CallDoWorkAndSignalTask::Run() { if (!work_) { // This can happen during tests or cases where there are more than just the diff --git a/chrome/browser/sync/glue/ui_model_worker.h b/chrome/browser/sync/glue/ui_model_worker.h index 84833d5..f7d9188 100644 --- a/chrome/browser/sync/glue/ui_model_worker.h +++ b/chrome/browser/sync/glue/ui_model_worker.h @@ -70,6 +70,7 @@ class UIModelWorker : public browser_sync::ModelSafeWorker { // ModelSafeWorker implementation. Called on syncapi SyncerThread. virtual void DoWorkAndWaitUntilDone(Closure* work); virtual ModelSafeGroup GetModelSafeGroup() { return GROUP_UI; } + virtual bool CurrentThreadIsWorkThread(); // Upon receiving this idempotent call, the ModelSafeWorker can // assume no work will ever be scheduled again from now on. If it has any work diff --git a/chrome/browser/sync/glue/ui_model_worker_unittest.cc b/chrome/browser/sync/glue/ui_model_worker_unittest.cc index a61832b..e0ad82f 100644 --- a/chrome/browser/sync/glue/ui_model_worker_unittest.cc +++ b/chrome/browser/sync/glue/ui_model_worker_unittest.cc @@ -55,7 +55,7 @@ class Syncer { }; // A task run from the SyncerThread to "sync share", ie tell the Syncer to -// ask it's ModelSafeWorker to do something. +// ask its ModelSafeWorker to do something. class FakeSyncShareTask : public Task { public: FakeSyncShareTask(Syncer* syncer, UIModelWorkerVisitor* visitor) |