| 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 "base/task/cancelable_task_tracker.h" |
| 6 | 6 |
| 7 #include <cstddef> | 7 #include <cstddef> |
| 8 #include <deque> | 8 #include <deque> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
| 18 #include "base/test/test_simple_task_runner.h" | 18 #include "base/test/test_simple_task_runner.h" |
| 19 #include "base/threading/thread.h" | 19 #include "base/threading/thread.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 21 |
| 22 namespace base { |
| 23 |
| 22 namespace { | 24 namespace { |
| 23 | 25 |
| 24 class CancelableTaskTrackerTest : public testing::Test { | 26 class CancelableTaskTrackerTest : public testing::Test { |
| 25 protected: | 27 protected: |
| 26 virtual ~CancelableTaskTrackerTest() { | 28 virtual ~CancelableTaskTrackerTest() { RunCurrentLoopUntilIdle(); } |
| 27 RunCurrentLoopUntilIdle(); | |
| 28 } | |
| 29 | 29 |
| 30 void RunCurrentLoopUntilIdle() { | 30 void RunCurrentLoopUntilIdle() { |
| 31 base::RunLoop run_loop; | 31 RunLoop run_loop; |
| 32 run_loop.RunUntilIdle(); | 32 run_loop.RunUntilIdle(); |
| 33 } | 33 } |
| 34 | 34 |
| 35 CancelableTaskTracker task_tracker_; | 35 CancelableTaskTracker task_tracker_; |
| 36 | 36 |
| 37 private: | 37 private: |
| 38 // Needed by CancelableTaskTracker methods. | 38 // Needed by CancelableTaskTracker methods. |
| 39 base::MessageLoop message_loop_; | 39 MessageLoop message_loop_; |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 void AddFailureAt(const tracked_objects::Location& location) { | 42 void AddFailureAt(const tracked_objects::Location& location) { |
| 43 ADD_FAILURE_AT(location.file_name(), location.line_number()); | 43 ADD_FAILURE_AT(location.file_name(), location.line_number()); |
| 44 } | 44 } |
| 45 | 45 |
| 46 // Returns a closure that fails if run. | 46 // Returns a closure that fails if run. |
| 47 base::Closure MakeExpectedNotRunClosure( | 47 Closure MakeExpectedNotRunClosure(const tracked_objects::Location& location) { |
| 48 const tracked_objects::Location& location) { | 48 return Bind(&AddFailureAt, location); |
| 49 return base::Bind(&AddFailureAt, location); | |
| 50 } | 49 } |
| 51 | 50 |
| 52 // A helper class for MakeExpectedRunClosure() that fails if it is | 51 // A helper class for MakeExpectedRunClosure() that fails if it is |
| 53 // destroyed without Run() having been called. This class may be used | 52 // destroyed without Run() having been called. This class may be used |
| 54 // from multiple threads as long as Run() is called at most once | 53 // from multiple threads as long as Run() is called at most once |
| 55 // before destruction. | 54 // before destruction. |
| 56 class RunChecker { | 55 class RunChecker { |
| 57 public: | 56 public: |
| 58 explicit RunChecker(const tracked_objects::Location& location) | 57 explicit RunChecker(const tracked_objects::Location& location) |
| 59 : location_(location), | 58 : location_(location), called_(false) {} |
| 60 called_(false) {} | |
| 61 | 59 |
| 62 ~RunChecker() { | 60 ~RunChecker() { |
| 63 if (!called_) { | 61 if (!called_) { |
| 64 ADD_FAILURE_AT(location_.file_name(), location_.line_number()); | 62 ADD_FAILURE_AT(location_.file_name(), location_.line_number()); |
| 65 } | 63 } |
| 66 } | 64 } |
| 67 | 65 |
| 68 void Run() { | 66 void Run() { called_ = true; } |
| 69 called_ = true; | |
| 70 } | |
| 71 | 67 |
| 72 private: | 68 private: |
| 73 tracked_objects::Location location_; | 69 tracked_objects::Location location_; |
| 74 bool called_; | 70 bool called_; |
| 75 }; | 71 }; |
| 76 | 72 |
| 77 // Returns a closure that fails on destruction if it hasn't been run. | 73 // Returns a closure that fails on destruction if it hasn't been run. |
| 78 base::Closure MakeExpectedRunClosure( | 74 Closure MakeExpectedRunClosure(const tracked_objects::Location& location) { |
| 79 const tracked_objects::Location& location) { | 75 return Bind(&RunChecker::Run, Owned(new RunChecker(location))); |
| 80 return base::Bind(&RunChecker::Run, base::Owned(new RunChecker(location))); | |
| 81 } | 76 } |
| 82 | 77 |
| 78 } // namespace |
| 79 |
| 83 // With the task tracker, post a task, a task with a reply, and get a | 80 // With the task tracker, post a task, a task with a reply, and get a |
| 84 // new task id without canceling any of them. The tasks and the reply | 81 // new task id without canceling any of them. The tasks and the reply |
| 85 // should run and the "is canceled" callback should return false. | 82 // should run and the "is canceled" callback should return false. |
| 86 TEST_F(CancelableTaskTrackerTest, NoCancel) { | 83 TEST_F(CancelableTaskTrackerTest, NoCancel) { |
| 87 base::Thread worker_thread("worker thread"); | 84 Thread worker_thread("worker thread"); |
| 88 ASSERT_TRUE(worker_thread.Start()); | 85 ASSERT_TRUE(worker_thread.Start()); |
| 89 | 86 |
| 90 ignore_result(task_tracker_.PostTask(worker_thread.message_loop_proxy().get(), | 87 ignore_result(task_tracker_.PostTask(worker_thread.message_loop_proxy().get(), |
| 91 FROM_HERE, | 88 FROM_HERE, |
| 92 MakeExpectedRunClosure(FROM_HERE))); | 89 MakeExpectedRunClosure(FROM_HERE))); |
| 93 | 90 |
| 94 ignore_result( | 91 ignore_result( |
| 95 task_tracker_.PostTaskAndReply(worker_thread.message_loop_proxy().get(), | 92 task_tracker_.PostTaskAndReply(worker_thread.message_loop_proxy().get(), |
| 96 FROM_HERE, | 93 FROM_HERE, |
| 97 MakeExpectedRunClosure(FROM_HERE), | 94 MakeExpectedRunClosure(FROM_HERE), |
| 98 MakeExpectedRunClosure(FROM_HERE))); | 95 MakeExpectedRunClosure(FROM_HERE))); |
| 99 | 96 |
| 100 CancelableTaskTracker::IsCanceledCallback is_canceled; | 97 CancelableTaskTracker::IsCanceledCallback is_canceled; |
| 101 ignore_result(task_tracker_.NewTrackedTaskId(&is_canceled)); | 98 ignore_result(task_tracker_.NewTrackedTaskId(&is_canceled)); |
| 102 | 99 |
| 103 worker_thread.Stop(); | 100 worker_thread.Stop(); |
| 104 | 101 |
| 105 RunCurrentLoopUntilIdle(); | 102 RunCurrentLoopUntilIdle(); |
| 106 | 103 |
| 107 EXPECT_FALSE(is_canceled.Run()); | 104 EXPECT_FALSE(is_canceled.Run()); |
| 108 } | 105 } |
| 109 | 106 |
| 110 // Post a task with the task tracker but cancel it before running the | 107 // Post a task with the task tracker but cancel it before running the |
| 111 // task runner. The task should not run. | 108 // task runner. The task should not run. |
| 112 TEST_F(CancelableTaskTrackerTest, CancelPostedTask) { | 109 TEST_F(CancelableTaskTrackerTest, CancelPostedTask) { |
| 113 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 110 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 114 new base::TestSimpleTaskRunner()); | 111 new TestSimpleTaskRunner()); |
| 115 | 112 |
| 116 CancelableTaskTracker::TaskId task_id = | 113 CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask( |
| 117 task_tracker_.PostTask( | 114 test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE)); |
| 118 test_task_runner.get(), | |
| 119 FROM_HERE, | |
| 120 MakeExpectedNotRunClosure(FROM_HERE)); | |
| 121 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 115 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
| 122 | 116 |
| 123 EXPECT_EQ(1U, test_task_runner->GetPendingTasks().size()); | 117 EXPECT_EQ(1U, test_task_runner->GetPendingTasks().size()); |
| 124 | 118 |
| 125 task_tracker_.TryCancel(task_id); | 119 task_tracker_.TryCancel(task_id); |
| 126 | 120 |
| 127 test_task_runner->RunUntilIdle(); | 121 test_task_runner->RunUntilIdle(); |
| 128 } | 122 } |
| 129 | 123 |
| 130 // Post a task with reply with the task tracker and cancel it before | 124 // Post a task with reply with the task tracker and cancel it before |
| 131 // running the task runner. Neither the task nor the reply should | 125 // running the task runner. Neither the task nor the reply should |
| 132 // run. | 126 // run. |
| 133 TEST_F(CancelableTaskTrackerTest, CancelPostedTaskAndReply) { | 127 TEST_F(CancelableTaskTrackerTest, CancelPostedTaskAndReply) { |
| 134 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 128 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 135 new base::TestSimpleTaskRunner()); | 129 new TestSimpleTaskRunner()); |
| 136 | 130 |
| 137 CancelableTaskTracker::TaskId task_id = | 131 CancelableTaskTracker::TaskId task_id = |
| 138 task_tracker_.PostTaskAndReply( | 132 task_tracker_.PostTaskAndReply(test_task_runner.get(), |
| 139 test_task_runner.get(), | 133 FROM_HERE, |
| 140 FROM_HERE, | 134 MakeExpectedNotRunClosure(FROM_HERE), |
| 141 MakeExpectedNotRunClosure(FROM_HERE), | 135 MakeExpectedNotRunClosure(FROM_HERE)); |
| 142 MakeExpectedNotRunClosure(FROM_HERE)); | |
| 143 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 136 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
| 144 | 137 |
| 145 task_tracker_.TryCancel(task_id); | 138 task_tracker_.TryCancel(task_id); |
| 146 | 139 |
| 147 test_task_runner->RunUntilIdle(); | 140 test_task_runner->RunUntilIdle(); |
| 148 } | 141 } |
| 149 | 142 |
| 150 // Post a task with reply with the task tracker and cancel it after | 143 // Post a task with reply with the task tracker and cancel it after |
| 151 // running the task runner but before running the current message | 144 // running the task runner but before running the current message |
| 152 // loop. The task should run but the reply should not. | 145 // loop. The task should run but the reply should not. |
| 153 TEST_F(CancelableTaskTrackerTest, CancelReply) { | 146 TEST_F(CancelableTaskTrackerTest, CancelReply) { |
| 154 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 147 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 155 new base::TestSimpleTaskRunner()); | 148 new TestSimpleTaskRunner()); |
| 156 | 149 |
| 157 CancelableTaskTracker::TaskId task_id = | 150 CancelableTaskTracker::TaskId task_id = |
| 158 task_tracker_.PostTaskAndReply( | 151 task_tracker_.PostTaskAndReply(test_task_runner.get(), |
| 159 test_task_runner.get(), | 152 FROM_HERE, |
| 160 FROM_HERE, | 153 MakeExpectedRunClosure(FROM_HERE), |
| 161 MakeExpectedRunClosure(FROM_HERE), | 154 MakeExpectedNotRunClosure(FROM_HERE)); |
| 162 MakeExpectedNotRunClosure(FROM_HERE)); | |
| 163 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 155 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
| 164 | 156 |
| 165 test_task_runner->RunUntilIdle(); | 157 test_task_runner->RunUntilIdle(); |
| 166 | 158 |
| 167 task_tracker_.TryCancel(task_id); | 159 task_tracker_.TryCancel(task_id); |
| 168 } | 160 } |
| 169 | 161 |
| 170 // Post a task with reply with the task tracker on a worker thread and | 162 // Post a task with reply with the task tracker on a worker thread and |
| 171 // cancel it before running the current message loop. The task should | 163 // cancel it before running the current message loop. The task should |
| 172 // run but the reply should not. | 164 // run but the reply should not. |
| 173 TEST_F(CancelableTaskTrackerTest, CancelReplyDifferentThread) { | 165 TEST_F(CancelableTaskTrackerTest, CancelReplyDifferentThread) { |
| 174 base::Thread worker_thread("worker thread"); | 166 Thread worker_thread("worker thread"); |
| 175 ASSERT_TRUE(worker_thread.Start()); | 167 ASSERT_TRUE(worker_thread.Start()); |
| 176 | 168 |
| 177 CancelableTaskTracker::TaskId task_id = | 169 CancelableTaskTracker::TaskId task_id = |
| 178 task_tracker_.PostTaskAndReply(worker_thread.message_loop_proxy().get(), | 170 task_tracker_.PostTaskAndReply(worker_thread.message_loop_proxy().get(), |
| 179 FROM_HERE, | 171 FROM_HERE, |
| 180 base::Bind(&base::DoNothing), | 172 Bind(&DoNothing), |
| 181 MakeExpectedNotRunClosure(FROM_HERE)); | 173 MakeExpectedNotRunClosure(FROM_HERE)); |
| 182 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 174 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
| 183 | 175 |
| 184 task_tracker_.TryCancel(task_id); | 176 task_tracker_.TryCancel(task_id); |
| 185 | 177 |
| 186 worker_thread.Stop(); | 178 worker_thread.Stop(); |
| 187 } | 179 } |
| 188 | 180 |
| 189 void ExpectIsCanceled( | 181 void ExpectIsCanceled( |
| 190 const CancelableTaskTracker::IsCanceledCallback& is_canceled, | 182 const CancelableTaskTracker::IsCanceledCallback& is_canceled, |
| 191 bool expected_is_canceled) { | 183 bool expected_is_canceled) { |
| 192 EXPECT_EQ(expected_is_canceled, is_canceled.Run()); | 184 EXPECT_EQ(expected_is_canceled, is_canceled.Run()); |
| 193 } | 185 } |
| 194 | 186 |
| 195 // Create a new task ID and check its status on a separate thread | 187 // Create a new task ID and check its status on a separate thread |
| 196 // before and after canceling. The is-canceled callback should be | 188 // before and after canceling. The is-canceled callback should be |
| 197 // thread-safe (i.e., nothing should blow up). | 189 // thread-safe (i.e., nothing should blow up). |
| 198 TEST_F(CancelableTaskTrackerTest, NewTrackedTaskIdDifferentThread) { | 190 TEST_F(CancelableTaskTrackerTest, NewTrackedTaskIdDifferentThread) { |
| 199 CancelableTaskTracker::IsCanceledCallback is_canceled; | 191 CancelableTaskTracker::IsCanceledCallback is_canceled; |
| 200 CancelableTaskTracker::TaskId task_id = | 192 CancelableTaskTracker::TaskId task_id = |
| 201 task_tracker_.NewTrackedTaskId(&is_canceled); | 193 task_tracker_.NewTrackedTaskId(&is_canceled); |
| 202 | 194 |
| 203 EXPECT_FALSE(is_canceled.Run()); | 195 EXPECT_FALSE(is_canceled.Run()); |
| 204 | 196 |
| 205 base::Thread other_thread("other thread"); | 197 Thread other_thread("other thread"); |
| 206 ASSERT_TRUE(other_thread.Start()); | 198 ASSERT_TRUE(other_thread.Start()); |
| 207 other_thread.message_loop_proxy()->PostTask( | 199 other_thread.message_loop_proxy()->PostTask( |
| 208 FROM_HERE, | 200 FROM_HERE, Bind(&ExpectIsCanceled, is_canceled, false)); |
| 209 base::Bind(&ExpectIsCanceled, is_canceled, false)); | |
| 210 other_thread.Stop(); | 201 other_thread.Stop(); |
| 211 | 202 |
| 212 task_tracker_.TryCancel(task_id); | 203 task_tracker_.TryCancel(task_id); |
| 213 | 204 |
| 214 ASSERT_TRUE(other_thread.Start()); | 205 ASSERT_TRUE(other_thread.Start()); |
| 215 other_thread.message_loop_proxy()->PostTask( | 206 other_thread.message_loop_proxy()->PostTask( |
| 216 FROM_HERE, | 207 FROM_HERE, Bind(&ExpectIsCanceled, is_canceled, true)); |
| 217 base::Bind(&ExpectIsCanceled, is_canceled, true)); | |
| 218 other_thread.Stop(); | 208 other_thread.Stop(); |
| 219 } | 209 } |
| 220 | 210 |
| 221 // With the task tracker, post a task, a task with a reply, get a new | 211 // With the task tracker, post a task, a task with a reply, get a new |
| 222 // task id, and then cancel all of them. None of the tasks nor the | 212 // task id, and then cancel all of them. None of the tasks nor the |
| 223 // reply should run and the "is canceled" callback should return | 213 // reply should run and the "is canceled" callback should return |
| 224 // true. | 214 // true. |
| 225 TEST_F(CancelableTaskTrackerTest, CancelAll) { | 215 TEST_F(CancelableTaskTrackerTest, CancelAll) { |
| 226 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 216 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 227 new base::TestSimpleTaskRunner()); | 217 new TestSimpleTaskRunner()); |
| 228 | 218 |
| 229 ignore_result(task_tracker_.PostTask( | 219 ignore_result(task_tracker_.PostTask( |
| 230 test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE))); | 220 test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE))); |
| 231 | 221 |
| 232 ignore_result( | 222 ignore_result( |
| 233 task_tracker_.PostTaskAndReply(test_task_runner.get(), | 223 task_tracker_.PostTaskAndReply(test_task_runner.get(), |
| 234 FROM_HERE, | 224 FROM_HERE, |
| 235 MakeExpectedNotRunClosure(FROM_HERE), | 225 MakeExpectedNotRunClosure(FROM_HERE), |
| 236 MakeExpectedNotRunClosure(FROM_HERE))); | 226 MakeExpectedNotRunClosure(FROM_HERE))); |
| 237 | 227 |
| 238 CancelableTaskTracker::IsCanceledCallback is_canceled; | 228 CancelableTaskTracker::IsCanceledCallback is_canceled; |
| 239 ignore_result(task_tracker_.NewTrackedTaskId(&is_canceled)); | 229 ignore_result(task_tracker_.NewTrackedTaskId(&is_canceled)); |
| 240 | 230 |
| 241 task_tracker_.TryCancelAll(); | 231 task_tracker_.TryCancelAll(); |
| 242 | 232 |
| 243 test_task_runner->RunUntilIdle(); | 233 test_task_runner->RunUntilIdle(); |
| 244 | 234 |
| 245 RunCurrentLoopUntilIdle(); | 235 RunCurrentLoopUntilIdle(); |
| 246 | 236 |
| 247 EXPECT_TRUE(is_canceled.Run()); | 237 EXPECT_TRUE(is_canceled.Run()); |
| 248 } | 238 } |
| 249 | 239 |
| 250 // With the task tracker, post a task, a task with a reply, get a new | 240 // With the task tracker, post a task, a task with a reply, get a new |
| 251 // task id, and then cancel all of them. None of the tasks nor the | 241 // task id, and then cancel all of them. None of the tasks nor the |
| 252 // reply should run and the "is canceled" callback should return | 242 // reply should run and the "is canceled" callback should return |
| 253 // true. | 243 // true. |
| 254 TEST_F(CancelableTaskTrackerTest, DestructionCancelsAll) { | 244 TEST_F(CancelableTaskTrackerTest, DestructionCancelsAll) { |
| 255 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 245 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 256 new base::TestSimpleTaskRunner()); | 246 new TestSimpleTaskRunner()); |
| 257 | 247 |
| 258 CancelableTaskTracker::IsCanceledCallback is_canceled; | 248 CancelableTaskTracker::IsCanceledCallback is_canceled; |
| 259 | 249 |
| 260 { | 250 { |
| 261 // Create another task tracker with a smaller scope. | 251 // Create another task tracker with a smaller scope. |
| 262 CancelableTaskTracker task_tracker; | 252 CancelableTaskTracker task_tracker; |
| 263 | 253 |
| 264 ignore_result(task_tracker.PostTask(test_task_runner.get(), | 254 ignore_result(task_tracker.PostTask(test_task_runner.get(), |
| 265 FROM_HERE, | 255 FROM_HERE, |
| 266 MakeExpectedNotRunClosure(FROM_HERE))); | 256 MakeExpectedNotRunClosure(FROM_HERE))); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 278 | 268 |
| 279 RunCurrentLoopUntilIdle(); | 269 RunCurrentLoopUntilIdle(); |
| 280 | 270 |
| 281 EXPECT_FALSE(is_canceled.Run()); | 271 EXPECT_FALSE(is_canceled.Run()); |
| 282 } | 272 } |
| 283 | 273 |
| 284 // Post a task and cancel it. HasTrackedTasks() should return true | 274 // Post a task and cancel it. HasTrackedTasks() should return true |
| 285 // from when the task is posted until the (do-nothing) reply task is | 275 // from when the task is posted until the (do-nothing) reply task is |
| 286 // flushed. | 276 // flushed. |
| 287 TEST_F(CancelableTaskTrackerTest, HasTrackedTasksPost) { | 277 TEST_F(CancelableTaskTrackerTest, HasTrackedTasksPost) { |
| 288 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 278 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 289 new base::TestSimpleTaskRunner()); | 279 new TestSimpleTaskRunner()); |
| 290 | 280 |
| 291 EXPECT_FALSE(task_tracker_.HasTrackedTasks()); | 281 EXPECT_FALSE(task_tracker_.HasTrackedTasks()); |
| 292 | 282 |
| 293 ignore_result(task_tracker_.PostTask( | 283 ignore_result(task_tracker_.PostTask( |
| 294 test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE))); | 284 test_task_runner.get(), FROM_HERE, MakeExpectedNotRunClosure(FROM_HERE))); |
| 295 | 285 |
| 296 task_tracker_.TryCancelAll(); | 286 task_tracker_.TryCancelAll(); |
| 297 | 287 |
| 298 test_task_runner->RunUntilIdle(); | 288 test_task_runner->RunUntilIdle(); |
| 299 | 289 |
| 300 EXPECT_TRUE(task_tracker_.HasTrackedTasks()); | 290 EXPECT_TRUE(task_tracker_.HasTrackedTasks()); |
| 301 | 291 |
| 302 RunCurrentLoopUntilIdle(); | 292 RunCurrentLoopUntilIdle(); |
| 303 | 293 |
| 304 EXPECT_FALSE(task_tracker_.HasTrackedTasks()); | 294 EXPECT_FALSE(task_tracker_.HasTrackedTasks()); |
| 305 } | 295 } |
| 306 | 296 |
| 307 // Post a task with a reply and cancel it. HasTrackedTasks() should | 297 // Post a task with a reply and cancel it. HasTrackedTasks() should |
| 308 // return true from when the task is posted until it is canceled. | 298 // return true from when the task is posted until it is canceled. |
| 309 TEST_F(CancelableTaskTrackerTest, HasTrackedTasksPostWithReply) { | 299 TEST_F(CancelableTaskTrackerTest, HasTrackedTasksPostWithReply) { |
| 310 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 300 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 311 new base::TestSimpleTaskRunner()); | 301 new TestSimpleTaskRunner()); |
| 312 | 302 |
| 313 EXPECT_FALSE(task_tracker_.HasTrackedTasks()); | 303 EXPECT_FALSE(task_tracker_.HasTrackedTasks()); |
| 314 | 304 |
| 315 ignore_result( | 305 ignore_result( |
| 316 task_tracker_.PostTaskAndReply(test_task_runner.get(), | 306 task_tracker_.PostTaskAndReply(test_task_runner.get(), |
| 317 FROM_HERE, | 307 FROM_HERE, |
| 318 MakeExpectedNotRunClosure(FROM_HERE), | 308 MakeExpectedNotRunClosure(FROM_HERE), |
| 319 MakeExpectedNotRunClosure(FROM_HERE))); | 309 MakeExpectedNotRunClosure(FROM_HERE))); |
| 320 | 310 |
| 321 task_tracker_.TryCancelAll(); | 311 task_tracker_.TryCancelAll(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 // good citizens there and undef the macro. | 354 // good citizens there and undef the macro. |
| 365 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) | 355 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) |
| 366 #define ENABLE_THREAD_CHECKER 1 | 356 #define ENABLE_THREAD_CHECKER 1 |
| 367 #else | 357 #else |
| 368 #define ENABLE_THREAD_CHECKER 0 | 358 #define ENABLE_THREAD_CHECKER 0 |
| 369 #endif | 359 #endif |
| 370 | 360 |
| 371 // Runs |fn| with |task_tracker|, expecting it to crash in debug mode. | 361 // Runs |fn| with |task_tracker|, expecting it to crash in debug mode. |
| 372 void MaybeRunDeadlyTaskTrackerMemberFunction( | 362 void MaybeRunDeadlyTaskTrackerMemberFunction( |
| 373 CancelableTaskTracker* task_tracker, | 363 CancelableTaskTracker* task_tracker, |
| 374 const base::Callback<void(CancelableTaskTracker*)>& fn) { | 364 const Callback<void(CancelableTaskTracker*)>& fn) { |
| 375 // CancelableTask uses DCHECKs with its ThreadChecker (itself only | 365 // CancelableTask uses DCHECKs with its ThreadChecker (itself only |
| 376 // enabled in debug mode). | 366 // enabled in debug mode). |
| 377 #if ENABLE_THREAD_CHECKER | 367 #if ENABLE_THREAD_CHECKER |
| 378 EXPECT_DEATH_IF_SUPPORTED(fn.Run(task_tracker), ""); | 368 EXPECT_DEATH_IF_SUPPORTED(fn.Run(task_tracker), ""); |
| 379 #endif | 369 #endif |
| 380 } | 370 } |
| 381 | 371 |
| 382 void PostDoNothingTask(CancelableTaskTracker* task_tracker) { | 372 void PostDoNothingTask(CancelableTaskTracker* task_tracker) { |
| 383 ignore_result( | 373 ignore_result(task_tracker->PostTask( |
| 384 task_tracker->PostTask(scoped_refptr<base::TestSimpleTaskRunner>( | 374 scoped_refptr<TestSimpleTaskRunner>(new TestSimpleTaskRunner()).get(), |
| 385 new base::TestSimpleTaskRunner()) | 375 FROM_HERE, |
| 386 .get(), | 376 Bind(&DoNothing))); |
| 387 FROM_HERE, | |
| 388 base::Bind(&base::DoNothing))); | |
| 389 } | 377 } |
| 390 | 378 |
| 391 TEST_F(CancelableTaskTrackerDeathTest, PostFromDifferentThread) { | 379 TEST_F(CancelableTaskTrackerDeathTest, PostFromDifferentThread) { |
| 392 base::Thread bad_thread("bad thread"); | 380 Thread bad_thread("bad thread"); |
| 393 ASSERT_TRUE(bad_thread.Start()); | 381 ASSERT_TRUE(bad_thread.Start()); |
| 394 | 382 |
| 395 bad_thread.message_loop_proxy()->PostTask( | 383 bad_thread.message_loop_proxy()->PostTask( |
| 396 FROM_HERE, | 384 FROM_HERE, |
| 397 base::Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, | 385 Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, |
| 398 base::Unretained(&task_tracker_), | 386 Unretained(&task_tracker_), |
| 399 base::Bind(&PostDoNothingTask))); | 387 Bind(&PostDoNothingTask))); |
| 400 } | 388 } |
| 401 | 389 |
| 402 void TryCancel(CancelableTaskTracker::TaskId task_id, | 390 void TryCancel(CancelableTaskTracker::TaskId task_id, |
| 403 CancelableTaskTracker* task_tracker) { | 391 CancelableTaskTracker* task_tracker) { |
| 404 task_tracker->TryCancel(task_id); | 392 task_tracker->TryCancel(task_id); |
| 405 } | 393 } |
| 406 | 394 |
| 407 TEST_F(CancelableTaskTrackerDeathTest, CancelOnDifferentThread) { | 395 TEST_F(CancelableTaskTrackerDeathTest, CancelOnDifferentThread) { |
| 408 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 396 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 409 new base::TestSimpleTaskRunner()); | 397 new TestSimpleTaskRunner()); |
| 410 | 398 |
| 411 base::Thread bad_thread("bad thread"); | 399 Thread bad_thread("bad thread"); |
| 412 ASSERT_TRUE(bad_thread.Start()); | 400 ASSERT_TRUE(bad_thread.Start()); |
| 413 | 401 |
| 414 CancelableTaskTracker::TaskId task_id = | 402 CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask( |
| 415 task_tracker_.PostTask( | 403 test_task_runner.get(), FROM_HERE, Bind(&DoNothing)); |
| 416 test_task_runner.get(), | |
| 417 FROM_HERE, | |
| 418 base::Bind(&base::DoNothing)); | |
| 419 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 404 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
| 420 | 405 |
| 421 bad_thread.message_loop_proxy()->PostTask( | 406 bad_thread.message_loop_proxy()->PostTask( |
| 422 FROM_HERE, | 407 FROM_HERE, |
| 423 base::Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, | 408 Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, |
| 424 base::Unretained(&task_tracker_), | 409 Unretained(&task_tracker_), |
| 425 base::Bind(&TryCancel, task_id))); | 410 Bind(&TryCancel, task_id))); |
| 426 | 411 |
| 427 test_task_runner->RunUntilIdle(); | 412 test_task_runner->RunUntilIdle(); |
| 428 } | 413 } |
| 429 | 414 |
| 430 TEST_F(CancelableTaskTrackerDeathTest, CancelAllOnDifferentThread) { | 415 TEST_F(CancelableTaskTrackerDeathTest, CancelAllOnDifferentThread) { |
| 431 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner( | 416 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
| 432 new base::TestSimpleTaskRunner()); | 417 new TestSimpleTaskRunner()); |
| 433 | 418 |
| 434 base::Thread bad_thread("bad thread"); | 419 Thread bad_thread("bad thread"); |
| 435 ASSERT_TRUE(bad_thread.Start()); | 420 ASSERT_TRUE(bad_thread.Start()); |
| 436 | 421 |
| 437 CancelableTaskTracker::TaskId task_id = | 422 CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask( |
| 438 task_tracker_.PostTask( | 423 test_task_runner.get(), FROM_HERE, Bind(&DoNothing)); |
| 439 test_task_runner.get(), | |
| 440 FROM_HERE, | |
| 441 base::Bind(&base::DoNothing)); | |
| 442 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 424 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
| 443 | 425 |
| 444 bad_thread.message_loop_proxy()->PostTask( | 426 bad_thread.message_loop_proxy()->PostTask( |
| 445 FROM_HERE, | 427 FROM_HERE, |
| 446 base::Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, | 428 Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, |
| 447 base::Unretained(&task_tracker_), | 429 Unretained(&task_tracker_), |
| 448 base::Bind(&CancelableTaskTracker::TryCancelAll))); | 430 Bind(&CancelableTaskTracker::TryCancelAll))); |
| 449 | 431 |
| 450 test_task_runner->RunUntilIdle(); | 432 test_task_runner->RunUntilIdle(); |
| 451 } | 433 } |
| 452 | 434 |
| 453 } // namespace | 435 } // namespace base |
| OLD | NEW |