OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "base/task/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/run_loop.h" | 17 #include "base/run_loop.h" |
17 #include "base/single_thread_task_runner.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 { | 22 namespace base { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 class CancelableTaskTrackerTest : public testing::Test { | 26 class CancelableTaskTrackerTest : public testing::Test { |
27 protected: | 27 protected: |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 | 77 |
78 } // namespace | 78 } // namespace |
79 | 79 |
80 // 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 |
81 // 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 |
82 // should run and the "is canceled" callback should return false. | 82 // should run and the "is canceled" callback should return false. |
83 TEST_F(CancelableTaskTrackerTest, NoCancel) { | 83 TEST_F(CancelableTaskTrackerTest, NoCancel) { |
84 Thread worker_thread("worker thread"); | 84 Thread worker_thread("worker thread"); |
85 ASSERT_TRUE(worker_thread.Start()); | 85 ASSERT_TRUE(worker_thread.Start()); |
86 | 86 |
87 ignore_result(task_tracker_.PostTask(worker_thread.task_runner().get(), | 87 ignore_result(task_tracker_.PostTask(worker_thread.message_loop_proxy().get(), |
88 FROM_HERE, | 88 FROM_HERE, |
89 MakeExpectedRunClosure(FROM_HERE))); | 89 MakeExpectedRunClosure(FROM_HERE))); |
90 | 90 |
91 ignore_result(task_tracker_.PostTaskAndReply( | 91 ignore_result( |
92 worker_thread.task_runner().get(), FROM_HERE, | 92 task_tracker_.PostTaskAndReply(worker_thread.message_loop_proxy().get(), |
93 MakeExpectedRunClosure(FROM_HERE), MakeExpectedRunClosure(FROM_HERE))); | 93 FROM_HERE, |
| 94 MakeExpectedRunClosure(FROM_HERE), |
| 95 MakeExpectedRunClosure(FROM_HERE))); |
94 | 96 |
95 CancelableTaskTracker::IsCanceledCallback is_canceled; | 97 CancelableTaskTracker::IsCanceledCallback is_canceled; |
96 ignore_result(task_tracker_.NewTrackedTaskId(&is_canceled)); | 98 ignore_result(task_tracker_.NewTrackedTaskId(&is_canceled)); |
97 | 99 |
98 worker_thread.Stop(); | 100 worker_thread.Stop(); |
99 | 101 |
100 RunCurrentLoopUntilIdle(); | 102 RunCurrentLoopUntilIdle(); |
101 | 103 |
102 EXPECT_FALSE(is_canceled.Run()); | 104 EXPECT_FALSE(is_canceled.Run()); |
103 } | 105 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 task_tracker_.TryCancel(task_id); | 159 task_tracker_.TryCancel(task_id); |
158 } | 160 } |
159 | 161 |
160 // 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 |
161 // cancel it before running the current message loop. The task should | 163 // cancel it before running the current message loop. The task should |
162 // run but the reply should not. | 164 // run but the reply should not. |
163 TEST_F(CancelableTaskTrackerTest, CancelReplyDifferentThread) { | 165 TEST_F(CancelableTaskTrackerTest, CancelReplyDifferentThread) { |
164 Thread worker_thread("worker thread"); | 166 Thread worker_thread("worker thread"); |
165 ASSERT_TRUE(worker_thread.Start()); | 167 ASSERT_TRUE(worker_thread.Start()); |
166 | 168 |
167 CancelableTaskTracker::TaskId task_id = task_tracker_.PostTaskAndReply( | 169 CancelableTaskTracker::TaskId task_id = |
168 worker_thread.task_runner().get(), FROM_HERE, Bind(&DoNothing), | 170 task_tracker_.PostTaskAndReply(worker_thread.message_loop_proxy().get(), |
169 MakeExpectedNotRunClosure(FROM_HERE)); | 171 FROM_HERE, |
| 172 Bind(&DoNothing), |
| 173 MakeExpectedNotRunClosure(FROM_HERE)); |
170 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 174 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
171 | 175 |
172 task_tracker_.TryCancel(task_id); | 176 task_tracker_.TryCancel(task_id); |
173 | 177 |
174 worker_thread.Stop(); | 178 worker_thread.Stop(); |
175 } | 179 } |
176 | 180 |
177 void ExpectIsCanceled( | 181 void ExpectIsCanceled( |
178 const CancelableTaskTracker::IsCanceledCallback& is_canceled, | 182 const CancelableTaskTracker::IsCanceledCallback& is_canceled, |
179 bool expected_is_canceled) { | 183 bool expected_is_canceled) { |
180 EXPECT_EQ(expected_is_canceled, is_canceled.Run()); | 184 EXPECT_EQ(expected_is_canceled, is_canceled.Run()); |
181 } | 185 } |
182 | 186 |
183 // 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 |
184 // before and after canceling. The is-canceled callback should be | 188 // before and after canceling. The is-canceled callback should be |
185 // thread-safe (i.e., nothing should blow up). | 189 // thread-safe (i.e., nothing should blow up). |
186 TEST_F(CancelableTaskTrackerTest, NewTrackedTaskIdDifferentThread) { | 190 TEST_F(CancelableTaskTrackerTest, NewTrackedTaskIdDifferentThread) { |
187 CancelableTaskTracker::IsCanceledCallback is_canceled; | 191 CancelableTaskTracker::IsCanceledCallback is_canceled; |
188 CancelableTaskTracker::TaskId task_id = | 192 CancelableTaskTracker::TaskId task_id = |
189 task_tracker_.NewTrackedTaskId(&is_canceled); | 193 task_tracker_.NewTrackedTaskId(&is_canceled); |
190 | 194 |
191 EXPECT_FALSE(is_canceled.Run()); | 195 EXPECT_FALSE(is_canceled.Run()); |
192 | 196 |
193 Thread other_thread("other thread"); | 197 Thread other_thread("other thread"); |
194 ASSERT_TRUE(other_thread.Start()); | 198 ASSERT_TRUE(other_thread.Start()); |
195 other_thread.task_runner()->PostTask( | 199 other_thread.message_loop_proxy()->PostTask( |
196 FROM_HERE, Bind(&ExpectIsCanceled, is_canceled, false)); | 200 FROM_HERE, Bind(&ExpectIsCanceled, is_canceled, false)); |
197 other_thread.Stop(); | 201 other_thread.Stop(); |
198 | 202 |
199 task_tracker_.TryCancel(task_id); | 203 task_tracker_.TryCancel(task_id); |
200 | 204 |
201 ASSERT_TRUE(other_thread.Start()); | 205 ASSERT_TRUE(other_thread.Start()); |
202 other_thread.task_runner()->PostTask( | 206 other_thread.message_loop_proxy()->PostTask( |
203 FROM_HERE, Bind(&ExpectIsCanceled, is_canceled, true)); | 207 FROM_HERE, Bind(&ExpectIsCanceled, is_canceled, true)); |
204 other_thread.Stop(); | 208 other_thread.Stop(); |
205 } | 209 } |
206 | 210 |
207 // 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 |
208 // 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 |
209 // reply should run and the "is canceled" callback should return | 213 // reply should run and the "is canceled" callback should return |
210 // true. | 214 // true. |
211 TEST_F(CancelableTaskTrackerTest, CancelAll) { | 215 TEST_F(CancelableTaskTrackerTest, CancelAll) { |
212 scoped_refptr<TestSimpleTaskRunner> test_task_runner( | 216 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 ignore_result(task_tracker->PostTask( | 371 ignore_result(task_tracker->PostTask( |
368 scoped_refptr<TestSimpleTaskRunner>(new TestSimpleTaskRunner()).get(), | 372 scoped_refptr<TestSimpleTaskRunner>(new TestSimpleTaskRunner()).get(), |
369 FROM_HERE, | 373 FROM_HERE, |
370 Bind(&DoNothing))); | 374 Bind(&DoNothing))); |
371 } | 375 } |
372 | 376 |
373 TEST_F(CancelableTaskTrackerDeathTest, PostFromDifferentThread) { | 377 TEST_F(CancelableTaskTrackerDeathTest, PostFromDifferentThread) { |
374 Thread bad_thread("bad thread"); | 378 Thread bad_thread("bad thread"); |
375 ASSERT_TRUE(bad_thread.Start()); | 379 ASSERT_TRUE(bad_thread.Start()); |
376 | 380 |
377 bad_thread.task_runner()->PostTask( | 381 bad_thread.message_loop_proxy()->PostTask( |
378 FROM_HERE, Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, | 382 FROM_HERE, |
379 Unretained(&task_tracker_), Bind(&PostDoNothingTask))); | 383 Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, |
| 384 Unretained(&task_tracker_), |
| 385 Bind(&PostDoNothingTask))); |
380 } | 386 } |
381 | 387 |
382 void TryCancel(CancelableTaskTracker::TaskId task_id, | 388 void TryCancel(CancelableTaskTracker::TaskId task_id, |
383 CancelableTaskTracker* task_tracker) { | 389 CancelableTaskTracker* task_tracker) { |
384 task_tracker->TryCancel(task_id); | 390 task_tracker->TryCancel(task_id); |
385 } | 391 } |
386 | 392 |
387 TEST_F(CancelableTaskTrackerDeathTest, CancelOnDifferentThread) { | 393 TEST_F(CancelableTaskTrackerDeathTest, CancelOnDifferentThread) { |
388 scoped_refptr<TestSimpleTaskRunner> test_task_runner( | 394 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
389 new TestSimpleTaskRunner()); | 395 new TestSimpleTaskRunner()); |
390 | 396 |
391 Thread bad_thread("bad thread"); | 397 Thread bad_thread("bad thread"); |
392 ASSERT_TRUE(bad_thread.Start()); | 398 ASSERT_TRUE(bad_thread.Start()); |
393 | 399 |
394 CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask( | 400 CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask( |
395 test_task_runner.get(), FROM_HERE, Bind(&DoNothing)); | 401 test_task_runner.get(), FROM_HERE, Bind(&DoNothing)); |
396 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 402 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
397 | 403 |
398 bad_thread.task_runner()->PostTask( | 404 bad_thread.message_loop_proxy()->PostTask( |
399 FROM_HERE, Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, | 405 FROM_HERE, |
400 Unretained(&task_tracker_), Bind(&TryCancel, task_id))); | 406 Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, |
| 407 Unretained(&task_tracker_), |
| 408 Bind(&TryCancel, task_id))); |
401 | 409 |
402 test_task_runner->RunUntilIdle(); | 410 test_task_runner->RunUntilIdle(); |
403 } | 411 } |
404 | 412 |
405 TEST_F(CancelableTaskTrackerDeathTest, CancelAllOnDifferentThread) { | 413 TEST_F(CancelableTaskTrackerDeathTest, CancelAllOnDifferentThread) { |
406 scoped_refptr<TestSimpleTaskRunner> test_task_runner( | 414 scoped_refptr<TestSimpleTaskRunner> test_task_runner( |
407 new TestSimpleTaskRunner()); | 415 new TestSimpleTaskRunner()); |
408 | 416 |
409 Thread bad_thread("bad thread"); | 417 Thread bad_thread("bad thread"); |
410 ASSERT_TRUE(bad_thread.Start()); | 418 ASSERT_TRUE(bad_thread.Start()); |
411 | 419 |
412 CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask( | 420 CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask( |
413 test_task_runner.get(), FROM_HERE, Bind(&DoNothing)); | 421 test_task_runner.get(), FROM_HERE, Bind(&DoNothing)); |
414 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); | 422 EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id); |
415 | 423 |
416 bad_thread.task_runner()->PostTask( | 424 bad_thread.message_loop_proxy()->PostTask( |
417 FROM_HERE, | 425 FROM_HERE, |
418 Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, Unretained(&task_tracker_), | 426 Bind(&MaybeRunDeadlyTaskTrackerMemberFunction, |
| 427 Unretained(&task_tracker_), |
419 Bind(&CancelableTaskTracker::TryCancelAll))); | 428 Bind(&CancelableTaskTracker::TryCancelAll))); |
420 | 429 |
421 test_task_runner->RunUntilIdle(); | 430 test_task_runner->RunUntilIdle(); |
422 } | 431 } |
423 | 432 |
424 } // namespace base | 433 } // namespace base |
OLD | NEW |