X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fsync%2Finternal_api%2Fpublic%2Fbase%2Fcancelation_signal_unittest.cc;h=63e4cb6a8676b5aa047a69324afcf016f59dcd51;hb=ff3e2503a20db9193d323c1d19c38c68004dec4a;hp=613e7560ede3769c2ee6182ba1649796da2e3255;hpb=7338fba38ba696536d1cc9d389afd716a6ab2fe6;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/sync/internal_api/public/base/cancelation_signal_unittest.cc b/src/sync/internal_api/public/base/cancelation_signal_unittest.cc index 613e756..63e4cb6 100644 --- a/src/sync/internal_api/public/base/cancelation_signal_unittest.cc +++ b/src/sync/internal_api/public/base/cancelation_signal_unittest.cc @@ -7,7 +7,9 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/synchronization/waitable_event.h" +#include "base/threading/platform_thread.h" #include "base/threading/thread.h" +#include "base/time/time.h" #include "sync/internal_api/public/base/cancelation_observer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,10 +21,15 @@ class BlockingTask : public CancelationObserver { virtual ~BlockingTask(); // Starts the |exec_thread_| and uses it to execute DoRun(). - void RunAsync(base::WaitableEvent* task_done_signal); + void RunAsync(base::WaitableEvent* task_start_signal, + base::WaitableEvent* task_done_signal); - // Blocks until canceled. Signals |task_done_signal| when finished. - void Run(base::WaitableEvent* task_done_signal); + // Blocks until canceled. Signals |task_done_signal| when finished (either + // via early cancel or cancel after start). Signals |task_start_signal| if + // and when the task starts successfully (which will not happen if the task + // was cancelled early). + void Run(base::WaitableEvent* task_start_signal, + base::WaitableEvent* task_done_signal); // Implementation of CancelationObserver. // Wakes up the thread blocked in Run(). @@ -46,21 +53,30 @@ BlockingTask::BlockingTask(CancelationSignal* cancel_signal) cancel_signal_(cancel_signal), was_started_(false) { } -BlockingTask::~BlockingTask() {} +BlockingTask::~BlockingTask() { + if (was_started_) { + cancel_signal_->UnregisterHandler(this); + } +} -void BlockingTask::RunAsync(base::WaitableEvent* task_done_signal) { +void BlockingTask::RunAsync(base::WaitableEvent* task_start_signal, + base::WaitableEvent* task_done_signal) { exec_thread_.Start(); exec_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&BlockingTask::Run, base::Unretained(this), + base::Unretained(task_start_signal), base::Unretained(task_done_signal))); } -void BlockingTask::Run(base::WaitableEvent* task_done_signal) { +void BlockingTask::Run( + base::WaitableEvent* task_start_signal, + base::WaitableEvent* task_done_signal) { if (cancel_signal_->TryRegisterHandler(this)) { DCHECK(!event_.IsSignaled()); was_started_ = true; + task_start_signal->Signal(); event_.Wait(); } task_done_signal->Signal(); @@ -79,19 +95,17 @@ class CancelationSignalTest : public ::testing::Test { CancelationSignalTest(); virtual ~CancelationSignalTest(); - // Starts the blocking task on a background thread. - void StartBlockingTask(); + // Starts the blocking task on a background thread. Does not wait for the + // task to start. + void StartBlockingTaskAsync(); + + // Starts the blocking task on a background thread. Does not return until + // the task has been started. + void StartBlockingTaskAndWaitForItToStart(); // Cancels the blocking task. void CancelBlocking(); - // Verifies that the background task is not running. This could be beacause - // it was canceled early or because it was canceled after it was started. - // - // This method may block for a brief period of time while waiting for the - // background thread to make progress. - bool VerifyTaskDone(); - // Verifies that the background task was canceled early. // // This method may block for a brief period of time while waiting for the @@ -102,27 +116,29 @@ class CancelationSignalTest : public ::testing::Test { base::MessageLoop main_loop_; CancelationSignal signal_; + base::WaitableEvent task_start_event_; base::WaitableEvent task_done_event_; BlockingTask blocking_task_; }; CancelationSignalTest::CancelationSignalTest() - : task_done_event_(false, false), blocking_task_(&signal_) {} + : task_start_event_(false, false), + task_done_event_(false, false), + blocking_task_(&signal_) {} CancelationSignalTest::~CancelationSignalTest() {} -void CancelationSignalTest::StartBlockingTask() { - blocking_task_.RunAsync(&task_done_event_); +void CancelationSignalTest::StartBlockingTaskAsync() { + blocking_task_.RunAsync(&task_start_event_, &task_done_event_); } -void CancelationSignalTest::CancelBlocking() { - signal_.Signal(); +void CancelationSignalTest::StartBlockingTaskAndWaitForItToStart() { + blocking_task_.RunAsync(&task_start_event_, &task_done_event_); + task_start_event_.Wait(); } -bool CancelationSignalTest::VerifyTaskDone() { - // Wait until BlockingTask::Run() has finished. - task_done_event_.Wait(); - return true; +void CancelationSignalTest::CancelBlocking() { + signal_.Signal(); } bool CancelationSignalTest::VerifyTaskNotStarted() { @@ -148,22 +164,23 @@ TEST(CancelationSignalTest_SingleThread, CheckFlags) { } // Send the cancelation signal before the task is started. This will ensure -// that the task will never be attempted. +// that the task will never be "started" (ie. TryRegisterHandler() will fail, +// so it will never start blocking on its main WaitableEvent). TEST_F(CancelationSignalTest, CancelEarly) { CancelBlocking(); - StartBlockingTask(); + StartBlockingTaskAsync(); EXPECT_TRUE(VerifyTaskNotStarted()); } -// Send the cancelation signal after the request to start the task has been -// posted. This is racy. The signal to stop may arrive before the signal to -// run the task. If that happens, we end up with another instance of the -// CancelEarly test defined earlier. If the signal requesting a stop arrives -// after the task has been started, it should end up stopping the task. +// Send the cancelation signal after the task has started running. This tests +// the non-early exit code path, where the task is stopped while it is in +// progress. TEST_F(CancelationSignalTest, Cancel) { - StartBlockingTask(); + StartBlockingTaskAndWaitForItToStart(); + + // Wait for the task to finish and let verify it has been started. CancelBlocking(); - EXPECT_TRUE(VerifyTaskDone()); + EXPECT_FALSE(VerifyTaskNotStarted()); } } // namespace syncer