| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/cancelable_task_tracker.h" | 5 #include "chrome/common/cancelable_task_tracker.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 | 60 |
| 61 // Block server thread so we can prepare the test. | 61 // Block server thread so we can prepare the test. |
| 62 task_thread_runner_->PostTask( | 62 task_thread_runner_->PostTask( |
| 63 FROM_HERE, | 63 FROM_HERE, |
| 64 Bind(&WaitableEvent::Wait, Unretained(&task_thread_start_event_))); | 64 Bind(&WaitableEvent::Wait, Unretained(&task_thread_start_event_))); |
| 65 } | 65 } |
| 66 | 66 |
| 67 virtual void TearDown() { | 67 virtual void TearDown() { |
| 68 UnblockTaskThread(); | 68 UnblockTaskThread(); |
| 69 | 69 |
| 70 // Create tracker on client thread. | 70 // Destroy tracker on client thread. |
| 71 WaitableEvent tracker_destroyed(true, false); | 71 WaitableEvent tracker_destroyed(true, false); |
| 72 client_thread_runner_->PostTask( | 72 client_thread_runner_->PostTask( |
| 73 FROM_HERE, | 73 FROM_HERE, |
| 74 Bind(&CancelableTaskTrackerTest::DestroyTrackerOnClientThread, | 74 Bind(&CancelableTaskTrackerTest::DestroyTrackerOnClientThread, |
| 75 Unretained(this), &tracker_destroyed)); | 75 Unretained(this), &tracker_destroyed)); |
| 76 |
| 77 // This will also wait for any pending tasks on client thread. |
| 76 tracker_destroyed.Wait(); | 78 tracker_destroyed.Wait(); |
| 77 | 79 |
| 78 client_thread_->Stop(); | 80 client_thread_->Stop(); |
| 79 task_thread_->Stop(); | 81 task_thread_->Stop(); |
| 80 } | 82 } |
| 81 | 83 |
| 82 void RunOnClientAndWait( | 84 void RunOnClientAndWait( |
| 83 void (*func)(CancelableTaskTrackerTest*, WaitableEvent*)) { | 85 void (*func)(CancelableTaskTrackerTest*, WaitableEvent*)) { |
| 84 WaitableEvent event(true, false); | 86 WaitableEvent event(true, false); |
| 85 client_thread_runner_->PostTask(FROM_HERE, | 87 client_thread_runner_->PostTask(FROM_HERE, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 105 | 107 |
| 106 ////////////////////////////////////////////////////////////////////////////// | 108 ////////////////////////////////////////////////////////////////////////////// |
| 107 // Testing data and related functions | 109 // Testing data and related functions |
| 108 int test_data_; // Defaults to 0. | 110 int test_data_; // Defaults to 0. |
| 109 | 111 |
| 110 Closure IncreaseTestDataAndSignalClosure(WaitableEvent* event) { | 112 Closure IncreaseTestDataAndSignalClosure(WaitableEvent* event) { |
| 111 return Bind(&CancelableTaskTrackerTest::IncreaseDataAndSignal, | 113 return Bind(&CancelableTaskTrackerTest::IncreaseDataAndSignal, |
| 112 &test_data_, event); | 114 &test_data_, event); |
| 113 } | 115 } |
| 114 | 116 |
| 117 Closure IncreaseTestDataIfNotCanceledAndSignalClosure( |
| 118 const CancelableTaskTracker::IsCanceledCallback& is_canceled_cb, |
| 119 WaitableEvent* event) { |
| 120 return Bind(&CancelableTaskTrackerTest::IncreaseDataIfNotCanceledAndSignal, |
| 121 &test_data_, is_canceled_cb, event); |
| 122 } |
| 123 |
| 115 Closure DecreaseTestDataClosure(WaitableEvent* event) { | 124 Closure DecreaseTestDataClosure(WaitableEvent* event) { |
| 116 return Bind(&CancelableTaskTrackerTest::DecreaseData, | 125 return Bind(&CancelableTaskTrackerTest::DecreaseData, |
| 117 Owned(new WaitableEventScoper(event)), &test_data_); | 126 Owned(new WaitableEventScoper(event)), &test_data_); |
| 118 } | 127 } |
| 119 | 128 |
| 120 private: | 129 private: |
| 121 void CreateTrackerOnClientThread(WaitableEvent* event) { | 130 void CreateTrackerOnClientThread(WaitableEvent* event) { |
| 122 tracker_.reset(new CancelableTaskTracker()); | 131 tracker_.reset(new CancelableTaskTracker()); |
| 123 event->Signal(); | 132 event->Signal(); |
| 124 } | 133 } |
| 125 | 134 |
| 126 void DestroyTrackerOnClientThread(WaitableEvent* event) { | 135 void DestroyTrackerOnClientThread(WaitableEvent* event) { |
| 127 tracker_.reset(); | 136 tracker_.reset(); |
| 128 event->Signal(); | 137 event->Signal(); |
| 129 } | 138 } |
| 130 | 139 |
| 131 static void IncreaseDataAndSignal(int* data, WaitableEvent* event) { | 140 static void IncreaseDataAndSignal(int* data, WaitableEvent* event) { |
| 132 (*data)++; | 141 (*data)++; |
| 133 if (event) | 142 if (event) |
| 134 event->Signal(); | 143 event->Signal(); |
| 135 } | 144 } |
| 136 | 145 |
| 146 static void IncreaseDataIfNotCanceledAndSignal( |
| 147 int* data, |
| 148 const CancelableTaskTracker::IsCanceledCallback& is_canceled_cb, |
| 149 WaitableEvent* event) { |
| 150 if (!is_canceled_cb.Run()) |
| 151 (*data)++; |
| 152 if (event) |
| 153 event->Signal(); |
| 154 } |
| 155 |
| 137 static void DecreaseData(WaitableEventScoper* event_scoper, int* data) { | 156 static void DecreaseData(WaitableEventScoper* event_scoper, int* data) { |
| 138 (*data) -= 2; | 157 (*data) -= 2; |
| 139 } | 158 } |
| 140 | 159 |
| 141 scoped_ptr<Thread> client_thread_; | 160 scoped_ptr<Thread> client_thread_; |
| 142 scoped_ptr<Thread> task_thread_; | 161 scoped_ptr<Thread> task_thread_; |
| 143 | 162 |
| 144 WaitableEvent task_thread_start_event_; | 163 WaitableEvent task_thread_start_event_; |
| 145 }; | 164 }; |
| 146 | 165 |
| 147 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST | 166 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST |
| 167 |
| 148 typedef CancelableTaskTrackerTest CancelableTaskTrackerDeathTest; | 168 typedef CancelableTaskTrackerTest CancelableTaskTrackerDeathTest; |
| 149 | 169 |
| 150 TEST_F(CancelableTaskTrackerDeathTest, PostFromDifferentThread) { | 170 TEST_F(CancelableTaskTrackerDeathTest, PostFromDifferentThread) { |
| 151 // The default style "fast" does not support multi-threaded tests. | 171 // The default style "fast" does not support multi-threaded tests. |
| 152 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 172 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
| 153 | 173 |
| 154 EXPECT_DEATH( | 174 EXPECT_DEATH( |
| 155 tracker_->PostTask(task_thread_runner_, | 175 tracker_->PostTask(task_thread_runner_, |
| 156 FROM_HERE, | 176 FROM_HERE, |
| 157 DecreaseTestDataClosure(NULL)), | 177 DecreaseTestDataClosure(NULL)), |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 // started yet (because this function is still running on client thread). | 338 // started yet (because this function is still running on client thread). |
| 319 // Now delete the tracker to cancel reply. | 339 // Now delete the tracker to cancel reply. |
| 320 test->tracker_.reset(); | 340 test->tracker_.reset(); |
| 321 } | 341 } |
| 322 | 342 |
| 323 TEST_F(CancelableTaskTrackerTest, TrackerDestructedAfterTask) { | 343 TEST_F(CancelableTaskTrackerTest, TrackerDestructedAfterTask) { |
| 324 RunOnClientAndWait(&TrackerDestructedAfterTask_Test); | 344 RunOnClientAndWait(&TrackerDestructedAfterTask_Test); |
| 325 EXPECT_EQ(1, test_data_); | 345 EXPECT_EQ(1, test_data_); |
| 326 } | 346 } |
| 327 | 347 |
| 348 void CheckTrackedTaskIdOnSameThread_Test(CancelableTaskTrackerTest* test, |
| 349 WaitableEvent* event) { |
| 350 CancelableTaskTracker::IsCanceledCallback is_canceled_cb; |
| 351 test->task_id_ = test->tracker_->NewTrackedTaskId(&is_canceled_cb); |
| 352 ASSERT_NE(CancelableTaskTracker::kBadTaskId, test->task_id_); |
| 353 |
| 354 EXPECT_FALSE(is_canceled_cb.Run()); |
| 355 |
| 356 test->tracker_->TryCancel(test->task_id_); |
| 357 EXPECT_TRUE(is_canceled_cb.Run()); |
| 358 |
| 359 test->task_id_ = test->tracker_->NewTrackedTaskId(&is_canceled_cb); |
| 360 EXPECT_FALSE(is_canceled_cb.Run()); |
| 361 |
| 362 // Destroy tracker will cancel all tasks. |
| 363 test->tracker_.reset(); |
| 364 EXPECT_TRUE(is_canceled_cb.Run()); |
| 365 |
| 366 event->Signal(); |
| 367 } |
| 368 |
| 369 TEST_F(CancelableTaskTrackerTest, CheckTrackedTaskIdOnSameThread) { |
| 370 RunOnClientAndWait(&CheckTrackedTaskIdOnSameThread_Test); |
| 371 } |
| 372 |
| 373 void CheckTrackedTaskIdOnDifferentThread_Test(CancelableTaskTrackerTest* test, |
| 374 WaitableEvent* event) { |
| 375 CancelableTaskTracker::IsCanceledCallback is_canceled_cb; |
| 376 test->task_id_ = test->tracker_->NewTrackedTaskId(&is_canceled_cb); |
| 377 ASSERT_NE(CancelableTaskTracker::kBadTaskId, test->task_id_); |
| 378 |
| 379 // Post task to task thread. |
| 380 test->task_thread_runner_->PostTask( |
| 381 FROM_HERE, |
| 382 test->IncreaseTestDataIfNotCanceledAndSignalClosure(is_canceled_cb, |
| 383 event)); |
| 384 is_canceled_cb.Reset(); // So the one in task thread runner is the last ref, |
| 385 // and will be destroyed on task thread. |
| 386 |
| 387 test->tracker_->TryCancel(test->task_id_); |
| 388 test->UnblockTaskThread(); |
| 389 } |
| 390 |
| 391 TEST_F(CancelableTaskTrackerTest, CheckTrackedTaskIdOnDifferentThread) { |
| 392 RunOnClientAndWait(&CheckTrackedTaskIdOnDifferentThread_Test); |
| 393 EXPECT_EQ(0, test_data_); |
| 394 } |
| 395 |
| 328 } // namespace | 396 } // namespace |
| OLD | NEW |