diff options
author | Ben Murdoch <benm@google.com> | 2014-11-06 12:50:09 +0000 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2014-11-06 12:50:09 +0000 |
commit | 5b892326406927b709cdaf6c384d4ababf456332 (patch) | |
tree | c2b36e6a80232b23731b9b3be8f5b7701382dfcb /chrome/browser/sync/glue | |
parent | 17d46637767dc9c540d984794ad6b5162e8c8c4f (diff) | |
download | chromium_org-5b892326406927b709cdaf6c384d4ababf456332.tar.gz |
Merge from Chromium at DEPS revision 39.0.2171.53
This commit was generated by merge_to_master.py.
Change-Id: Id583a0dc312e50e455eb8bd04f75c74304738c9d
Diffstat (limited to 'chrome/browser/sync/glue')
5 files changed, 91 insertions, 4 deletions
diff --git a/chrome/browser/sync/glue/browser_thread_model_worker.cc b/chrome/browser/sync/glue/browser_thread_model_worker.cc index 7f4024af61..093d2828bf 100644 --- a/chrome/browser/sync/glue/browser_thread_model_worker.cc +++ b/chrome/browser/sync/glue/browser_thread_model_worker.cc @@ -50,7 +50,6 @@ BrowserThreadModelWorker::~BrowserThreadModelWorker() {} void BrowserThreadModelWorker::RegisterForLoopDestruction() { if (BrowserThread::CurrentlyOn(thread_)) { - base::MessageLoop::current()->AddDestructionObserver(this); SetWorkingLoopToCurrent(); } else { BrowserThread::PostTask( diff --git a/chrome/browser/sync/glue/history_model_worker.cc b/chrome/browser/sync/glue/history_model_worker.cc index 179637b33f..fec3f1e3a9 100644 --- a/chrome/browser/sync/glue/history_model_worker.cc +++ b/chrome/browser/sync/glue/history_model_worker.cc @@ -100,7 +100,6 @@ void HistoryModelWorker::RegisterForLoopDestruction() { } void HistoryModelWorker::RegisterOnDBThread() { - base::MessageLoop::current()->AddDestructionObserver(this); SetWorkingLoopToCurrent(); } diff --git a/chrome/browser/sync/glue/password_model_worker.cc b/chrome/browser/sync/glue/password_model_worker.cc index 6ad5cfd8a0..17ba62ee2d 100644 --- a/chrome/browser/sync/glue/password_model_worker.cc +++ b/chrome/browser/sync/glue/password_model_worker.cc @@ -64,7 +64,6 @@ void PasswordModelWorker::CallDoWorkAndSignalTask( } void PasswordModelWorker::RegisterForPasswordLoopDestruction() { - base::MessageLoop::current()->AddDestructionObserver(this); SetWorkingLoopToCurrent(); } diff --git a/chrome/browser/sync/glue/sync_backend_registrar_unittest.cc b/chrome/browser/sync/glue/sync_backend_registrar_unittest.cc index cd2d29ddf4..e6e39d487a 100644 --- a/chrome/browser/sync/glue/sync_backend_registrar_unittest.cc +++ b/chrome/browser/sync/glue/sync_backend_registrar_unittest.cc @@ -4,6 +4,7 @@ #include "chrome/browser/sync/glue/sync_backend_registrar.h" +#include "base/run_loop.h" #include "chrome/browser/sync/glue/ui_model_worker.h" #include "chrome/test/base/testing_profile.h" #include "components/sync_driver/change_processor_mock.h" @@ -256,6 +257,96 @@ TEST_F(SyncBackendRegistrarTest, ActivateDeactivateNonUIDataType) { TriggerChanges(registrar_.get(), AUTOFILL); } +class SyncBackendRegistrarShutdownTest : public testing::Test { + public: + void BlockDBThread() { + EXPECT_FALSE(db_thread_lock_.Try()); + + db_thread_blocked_.Signal(); + base::AutoLock l(db_thread_lock_); + } + + protected: + friend class TestRegistrar; + + SyncBackendRegistrarShutdownTest() + : thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD | + content::TestBrowserThreadBundle::REAL_FILE_THREAD | + content::TestBrowserThreadBundle::REAL_IO_THREAD), + db_thread_blocked_(false, false) { + quit_closure_ = run_loop_.QuitClosure(); + } + + virtual ~SyncBackendRegistrarShutdownTest() {} + + void PostQuitOnUIMessageLoop() { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_closure_); + } + + content::TestBrowserThreadBundle thread_bundle_; + TestingProfile profile_; + base::WaitableEvent db_thread_blocked_; + base::Lock db_thread_lock_; + base::RunLoop run_loop_; + base::Closure quit_closure_; +}; + +// Wrap SyncBackendRegistrar so that we can monitor its lifetime. +class TestRegistrar : public SyncBackendRegistrar { + public: + explicit TestRegistrar(Profile* profile, + SyncBackendRegistrarShutdownTest* test) + : SyncBackendRegistrar("test", profile, scoped_ptr<base::Thread>()), + test_(test) {} + + virtual ~TestRegistrar() { test_->PostQuitOnUIMessageLoop(); } + + private: + SyncBackendRegistrarShutdownTest* test_; +}; + +TEST_F(SyncBackendRegistrarShutdownTest, BlockingShutdown) { + // Take ownership of |db_thread_lock_| so that the DB thread can't acquire it. + db_thread_lock_.Acquire(); + + // This will block the DB thread by waiting on |db_thread_lock_|. + BrowserThread::PostTask( + BrowserThread::DB, + FROM_HERE, + base::Bind(&SyncBackendRegistrarShutdownTest::BlockDBThread, + base::Unretained(this))); + + scoped_ptr<TestRegistrar> registrar(new TestRegistrar(&profile_, this)); + base::Thread* sync_thread = registrar->sync_thread(); + + // Stop here until the DB thread gets a chance to run and block on the lock. + // Please note that since the task above didn't finish, the task to + // initialize the worker on the DB thread hasn't had a chance to run yet too. + // Which means ModelSafeWorker::SetWorkingLoopToCurrent hasn't been called + // for the DB worker. + db_thread_blocked_.Wait(); + + registrar->SetInitialTypes(ModelTypeSet()); + + // Start the shutdown. + registrar->RequestWorkerStopOnUIThread(); + + sync_thread->message_loop()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendRegistrar::Shutdown, + base::Unretained(registrar.release()))); + + // The test verifies that the sync thread doesn't block because + // of the blocked DB thread and can finish the shutdown. + sync_thread->message_loop()->RunUntilIdle(); + + db_thread_lock_.Release(); + + // Run the main thread loop until all workers have been removed and the + // registrar destroyed. + run_loop_.Run(); +} + } // namespace } // namespace browser_sync diff --git a/chrome/browser/sync/glue/ui_model_worker.cc b/chrome/browser/sync/glue/ui_model_worker.cc index 2d8bc7d143..726deb6dfc 100644 --- a/chrome/browser/sync/glue/ui_model_worker.cc +++ b/chrome/browser/sync/glue/ui_model_worker.cc @@ -47,7 +47,6 @@ UIModelWorker::UIModelWorker(syncer::WorkerLoopDestructionObserver* observer) void UIModelWorker::RegisterForLoopDestruction() { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - base::MessageLoop::current()->AddDestructionObserver(this); SetWorkingLoopToCurrent(); } |