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

Unified Diff: components/sync/driver/glue/ui_model_worker_unittest.cc

Issue 2496723003: [Sync] Signal UIModelWorker to abort on sync shutdown. (Closed)
Patch Set: Address comments + add test. Created 4 years, 1 month 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: components/sync/driver/glue/ui_model_worker_unittest.cc
diff --git a/components/sync/driver/glue/ui_model_worker_unittest.cc b/components/sync/driver/glue/ui_model_worker_unittest.cc
index d091f317a5c60f2896c0a05ec84abbea9095a730..ce401bf1684dbbf5f6bf38c24534b3c51b61573b 100644
--- a/components/sync/driver/glue/ui_model_worker_unittest.cc
+++ b/components/sync/driver/glue/ui_model_worker_unittest.cc
@@ -32,6 +32,15 @@ WorkCallback ClosureToWorkCallback(base::Closure work) {
return base::Bind(&DoWork, base::ThreadTaskRunnerHandle::Get(), work);
}
+// This function runs on the sync thread.
+void SignalAndDoWork(scoped_refptr<UIModelWorker> worker,
+ WorkCallback work,
+ base::WaitableEvent* event) {
+ if (event)
fdoray 2016/11/14 14:24:34 EXPECT_TRUE(event) since we don't expect |event| t
maxbogue 2016/11/14 20:53:21 n/a, event is no longer needed.
+ event->Signal();
+ worker->DoWorkAndWaitUntilDone(work);
+}
+
class SyncUIModelWorkerTest : public testing::Test {
public:
SyncUIModelWorkerTest() : sync_thread_("SyncThreadForTest") {
@@ -39,25 +48,54 @@ class SyncUIModelWorkerTest : public testing::Test {
worker_ = new UIModelWorker(base::ThreadTaskRunnerHandle::Get());
}
- void PostWorkToSyncThread(WorkCallback work) {
+ void PostWorkToSyncThread(base::Closure work,
+ base::WaitableEvent* task_on_sync_thread_event) {
sync_thread_.task_runner()->PostTask(
FROM_HERE,
- base::Bind(base::IgnoreResult(&UIModelWorker::DoWorkAndWaitUntilDone),
- worker_, work));
+ base::Bind(&SignalAndDoWork, worker_, ClosureToWorkCallback(work),
+ task_on_sync_thread_event));
}
+ void StopSyncThread() { sync_thread_.Stop(); }
+
+ UIModelWorker* worker() { return worker_.get(); }
+
private:
+ // Worker must outlive message loop.
+ scoped_refptr<UIModelWorker> worker_;
base::MessageLoop ui_loop_;
base::Thread sync_thread_;
- scoped_refptr<UIModelWorker> worker_;
};
TEST_F(SyncUIModelWorkerTest, ScheduledWorkRunsOnUILoop) {
base::RunLoop run_loop;
- PostWorkToSyncThread(ClosureToWorkCallback(run_loop.QuitClosure()));
+ PostWorkToSyncThread(run_loop.QuitClosure(), nullptr);
// This won't quit until the QuitClosure is run.
run_loop.Run();
}
+TEST_F(SyncUIModelWorkerTest, ShutdownNoDeadlock) {
+ // We need some way to wait until the sync thread has our task.
+ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+ PostWorkToSyncThread(base::Bind(&SyncUIModelWorkerTest::StopSyncThread,
+ base::Unretained(this)),
+ &event);
+
+ // Wait until the sync thread has started our task.
+ event.Wait();
+
+ // This is a little racy. We're banking on this stop signal to occur after the
+ // sync thread has progressed past the stopped check. However, if it doesn't,
+ // we just get a false positive (no flakes).
fdoray 2016/11/14 14:24:34 I think the test below avoids false positives (the
maxbogue 2016/11/14 20:53:21 Of course, just do everything inside the work clos
+ worker()->RequestStop();
+
+ // Now we yield control of the UI thread. The stop signal has unblocked the
+ // sync thread, so the UI thread task can join the sync thread without
+ // deadlocking.
+ base::RunLoop().RunUntilIdle();
+}
+
} // namespace
} // namespace syncer

Powered by Google App Engine
This is Rietveld 408576698