OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/threading/sequenced_worker_pool.h" | 5 #include "base/threading/sequenced_worker_pool.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
| 11 #include <utility> |
11 | 12 |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
13 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
14 #include "base/macros.h" | 15 #include "base/macros.h" |
15 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
16 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
17 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
18 #include "base/synchronization/condition_variable.h" | 19 #include "base/synchronization/condition_variable.h" |
19 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
| 21 #include "base/task_scheduler/scheduler_worker_pool_params.h" |
| 22 #include "base/task_scheduler/task_scheduler.h" |
| 23 #include "base/task_scheduler/task_scheduler_impl.h" |
20 #include "base/test/sequenced_task_runner_test_template.h" | 24 #include "base/test/sequenced_task_runner_test_template.h" |
21 #include "base/test/sequenced_worker_pool_owner.h" | 25 #include "base/test/sequenced_worker_pool_owner.h" |
22 #include "base/test/task_runner_test_template.h" | 26 #include "base/test/task_runner_test_template.h" |
23 #include "base/test/test_timeouts.h" | 27 #include "base/test/test_timeouts.h" |
24 #include "base/threading/platform_thread.h" | 28 #include "base/threading/platform_thread.h" |
25 #include "base/time/time.h" | 29 #include "base/time/time.h" |
26 #include "base/tracked_objects.h" | 30 #include "base/tracked_objects.h" |
27 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
28 | 32 |
29 namespace base { | 33 namespace base { |
30 | 34 |
31 // IMPORTANT NOTE: | 35 // IMPORTANT NOTE: |
32 // | 36 // |
33 // Many of these tests have failure modes where they'll hang forever. These | 37 // Many of these tests have failure modes where they'll hang forever. These |
34 // tests should not be flaky, and hanging indicates a type of failure. Do not | 38 // tests should not be flaky, and hanging indicates a type of failure. Do not |
35 // mark as flaky if they're hanging, it's likely an actual bug. | 39 // mark as flaky if they're hanging, it's likely an actual bug. |
36 | 40 |
37 namespace { | 41 namespace { |
38 | 42 |
39 const size_t kNumWorkerThreads = 3; | 43 constexpr size_t kNumWorkerThreads = 3; |
| 44 constexpr size_t kNumAllowedBlockShutdownTasks = 1000; |
40 | 45 |
41 // Allows a number of threads to all be blocked on the same event, and | 46 // Allows a number of threads to all be blocked on the same event, and |
42 // provides a way to unblock a certain number of them. | 47 // provides a way to unblock a certain number of them. |
43 class ThreadBlocker { | 48 class ThreadBlocker { |
44 public: | 49 public: |
45 ThreadBlocker() : lock_(), cond_var_(&lock_), unblock_counter_(0) {} | 50 ThreadBlocker() : lock_(), cond_var_(&lock_), unblock_counter_(0) {} |
46 | 51 |
47 void Block() { | 52 void Block() { |
48 { | 53 { |
49 base::AutoLock lock(lock_); | 54 base::AutoLock lock(lock_); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 | 229 |
225 base::ConditionVariable cond_var_; | 230 base::ConditionVariable cond_var_; |
226 | 231 |
227 // Protected by lock_. | 232 // Protected by lock_. |
228 std::vector<int> complete_sequence_; | 233 std::vector<int> complete_sequence_; |
229 | 234 |
230 // Counter of the number of "block" workers that have started. | 235 // Counter of the number of "block" workers that have started. |
231 size_t started_events_; | 236 size_t started_events_; |
232 }; | 237 }; |
233 | 238 |
234 class SequencedWorkerPoolTest : public testing::Test { | 239 enum class SequencedWorkerPoolRedirection { NONE, TO_TASK_SCHEDULER }; |
| 240 |
| 241 void StartRedirectionToTaskScheduler(size_t num_threads) { |
| 242 std::vector<SchedulerWorkerPoolParams> worker_pool_params; |
| 243 worker_pool_params.emplace_back( |
| 244 "SchedulerWorkerPoolName", ThreadPriority::NORMAL, |
| 245 SchedulerWorkerPoolParams::IORestriction::ALLOWED, num_threads, |
| 246 TimeDelta::Max()); |
| 247 TaskScheduler::CreateAndSetDefaultTaskScheduler( |
| 248 std::move(worker_pool_params), |
| 249 base::Bind([](const TaskTraits&) -> size_t { return 0U; })); |
| 250 SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting(); |
| 251 SequencedWorkerPool::RedirectToTaskSchedulerForProcess(); |
| 252 } |
| 253 |
| 254 void StopRedirectionToTaskScheduler() { |
| 255 SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting(); |
| 256 static_cast<internal::TaskSchedulerImpl*>(TaskScheduler::GetInstance()) |
| 257 ->JoinForTesting(); |
| 258 TaskScheduler::SetInstance(nullptr); |
| 259 } |
| 260 |
| 261 class SequencedWorkerPoolTest |
| 262 : public testing::TestWithParam<SequencedWorkerPoolRedirection> { |
235 public: | 263 public: |
236 SequencedWorkerPoolTest() | 264 SequencedWorkerPoolTest() |
237 : tracker_(new TestTracker) { | 265 : tracker_(new TestTracker) { |
238 ResetPool(); | 266 ResetPool(); |
239 } | 267 } |
240 | 268 |
| 269 void SetUp() override { |
| 270 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 271 StartRedirectionToTaskScheduler(kNumWorkerThreads); |
| 272 } |
| 273 |
| 274 void TearDown() override { |
| 275 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 276 StopRedirectionToTaskScheduler(); |
| 277 } |
| 278 |
241 const scoped_refptr<SequencedWorkerPool>& pool() { | 279 const scoped_refptr<SequencedWorkerPool>& pool() { |
242 return pool_owner_->pool(); | 280 return pool_owner_->pool(); |
243 } | 281 } |
244 TestTracker* tracker() { return tracker_.get(); } | 282 TestTracker* tracker() { return tracker_.get(); } |
245 | 283 |
246 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut | 284 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut |
247 // down, and creates a new instance. | 285 // down, and creates a new instance. |
248 void ResetPool() { | 286 void ResetPool() { |
249 pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); | 287 pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); |
250 } | 288 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 const scoped_refptr<base::RefCountedData<bool> > deleted_flag_; | 363 const scoped_refptr<base::RefCountedData<bool> > deleted_flag_; |
326 DISALLOW_COPY_AND_ASSIGN(DeletionHelper); | 364 DISALLOW_COPY_AND_ASSIGN(DeletionHelper); |
327 }; | 365 }; |
328 | 366 |
329 void HoldPoolReference(const scoped_refptr<base::SequencedWorkerPool>& pool, | 367 void HoldPoolReference(const scoped_refptr<base::SequencedWorkerPool>& pool, |
330 const scoped_refptr<DeletionHelper>& helper) { | 368 const scoped_refptr<DeletionHelper>& helper) { |
331 ADD_FAILURE() << "Should never run"; | 369 ADD_FAILURE() << "Should never run"; |
332 } | 370 } |
333 | 371 |
334 // Tests that delayed tasks are deleted upon shutdown of the pool. | 372 // Tests that delayed tasks are deleted upon shutdown of the pool. |
335 TEST_F(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) { | 373 TEST_P(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) { |
336 // Post something to verify the pool is started up. | 374 // Post something to verify the pool is started up. |
337 EXPECT_TRUE(pool()->PostTask( | 375 EXPECT_TRUE(pool()->PostTask( |
338 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1))); | 376 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1))); |
339 | 377 |
340 scoped_refptr<base::RefCountedData<bool> > deleted_flag( | 378 scoped_refptr<base::RefCountedData<bool> > deleted_flag( |
341 new base::RefCountedData<bool>(false)); | 379 new base::RefCountedData<bool>(false)); |
342 | 380 |
343 base::Time posted_at(base::Time::Now()); | 381 base::Time posted_at(base::Time::Now()); |
344 // Post something that shouldn't run. | 382 // Post something that shouldn't run. |
345 EXPECT_TRUE(pool()->PostDelayedTask( | 383 EXPECT_TRUE(pool()->PostDelayedTask( |
346 FROM_HERE, | 384 FROM_HERE, |
347 base::Bind(&HoldPoolReference, | 385 base::Bind(&HoldPoolReference, |
348 pool(), | 386 pool(), |
349 make_scoped_refptr(new DeletionHelper(deleted_flag))), | 387 make_scoped_refptr(new DeletionHelper(deleted_flag))), |
350 TestTimeouts::action_timeout())); | 388 TestTimeouts::action_timeout())); |
351 | 389 |
352 std::vector<int> completion_sequence = tracker()->WaitUntilTasksComplete(1); | 390 std::vector<int> completion_sequence = tracker()->WaitUntilTasksComplete(1); |
353 ASSERT_EQ(1u, completion_sequence.size()); | 391 ASSERT_EQ(1u, completion_sequence.size()); |
354 ASSERT_EQ(1, completion_sequence[0]); | 392 ASSERT_EQ(1, completion_sequence[0]); |
355 | 393 |
356 // Shutdown is asynchronous, so use ResetPool() to block until the pool is | 394 if (GetParam() == SequencedWorkerPoolRedirection::NONE) { |
357 // fully destroyed (and thus shut down). | 395 // Wait until the pool is fully shut down and destroyed. |
358 ResetPool(); | 396 ResetPool(); |
| 397 } else { |
| 398 // Wait until the TaskScheduler is shut down. |
| 399 TaskScheduler::GetInstance()->Shutdown(); |
| 400 } |
359 | 401 |
360 // Verify that we didn't block until the task was due. | 402 // Verify that we didn't block until the task was due. |
361 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout()); | 403 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout()); |
362 | 404 |
363 // Verify that the deferred task has not only not run, but has also been | 405 // If tasks aren't redirected to the TaskScheduler, verify that the deferred |
364 // destroyed. | 406 // task has not only not run, but has also been destroyed. The TaskScheduler |
365 ASSERT_TRUE(deleted_flag->data); | 407 // doesn't destroy its tasks on shutdown. |
| 408 if (GetParam() == SequencedWorkerPoolRedirection::NONE) |
| 409 ASSERT_TRUE(deleted_flag->data); |
366 } | 410 } |
367 | 411 |
368 // Tests that same-named tokens have the same ID. | 412 // Tests that same-named tokens have the same ID. |
369 TEST_F(SequencedWorkerPoolTest, NamedTokens) { | 413 TEST_P(SequencedWorkerPoolTest, NamedTokens) { |
370 const std::string name1("hello"); | 414 const std::string name1("hello"); |
371 SequencedWorkerPool::SequenceToken token1 = | 415 SequencedWorkerPool::SequenceToken token1 = |
372 pool()->GetNamedSequenceToken(name1); | 416 pool()->GetNamedSequenceToken(name1); |
373 | 417 |
374 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); | 418 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); |
375 | 419 |
376 const std::string name3("goodbye"); | 420 const std::string name3("goodbye"); |
377 SequencedWorkerPool::SequenceToken token3 = | 421 SequencedWorkerPool::SequenceToken token3 = |
378 pool()->GetNamedSequenceToken(name3); | 422 pool()->GetNamedSequenceToken(name3); |
379 | 423 |
380 // All 3 tokens should be different. | 424 // All 3 tokens should be different. |
381 EXPECT_FALSE(token1.Equals(token2)); | 425 EXPECT_FALSE(token1.Equals(token2)); |
382 EXPECT_FALSE(token1.Equals(token3)); | 426 EXPECT_FALSE(token1.Equals(token3)); |
383 EXPECT_FALSE(token2.Equals(token3)); | 427 EXPECT_FALSE(token2.Equals(token3)); |
384 | 428 |
385 // Requesting the same name again should give the same value. | 429 // Requesting the same name again should give the same value. |
386 SequencedWorkerPool::SequenceToken token1again = | 430 SequencedWorkerPool::SequenceToken token1again = |
387 pool()->GetNamedSequenceToken(name1); | 431 pool()->GetNamedSequenceToken(name1); |
388 EXPECT_TRUE(token1.Equals(token1again)); | 432 EXPECT_TRUE(token1.Equals(token1again)); |
389 | 433 |
390 SequencedWorkerPool::SequenceToken token3again = | 434 SequencedWorkerPool::SequenceToken token3again = |
391 pool()->GetNamedSequenceToken(name3); | 435 pool()->GetNamedSequenceToken(name3); |
392 EXPECT_TRUE(token3.Equals(token3again)); | 436 EXPECT_TRUE(token3.Equals(token3again)); |
393 } | 437 } |
394 | 438 |
395 // Tests that posting a bunch of tasks (many more than the number of worker | 439 // Tests that posting a bunch of tasks (many more than the number of worker |
396 // threads) runs them all. | 440 // threads) runs them all. |
397 TEST_F(SequencedWorkerPoolTest, LotsOfTasks) { | 441 TEST_P(SequencedWorkerPoolTest, LotsOfTasks) { |
398 pool()->PostWorkerTask(FROM_HERE, | 442 pool()->PostWorkerTask(FROM_HERE, |
399 base::Bind(&TestTracker::SlowTask, tracker(), 0)); | 443 base::Bind(&TestTracker::SlowTask, tracker(), 0)); |
400 | 444 |
401 const size_t kNumTasks = 20; | 445 const size_t kNumTasks = 20; |
402 for (size_t i = 1; i < kNumTasks; i++) { | 446 for (size_t i = 1; i < kNumTasks; i++) { |
403 pool()->PostWorkerTask(FROM_HERE, | 447 pool()->PostWorkerTask(FROM_HERE, |
404 base::Bind(&TestTracker::FastTask, tracker(), i)); | 448 base::Bind(&TestTracker::FastTask, tracker(), i)); |
405 } | 449 } |
406 | 450 |
407 std::vector<int> result = tracker()->WaitUntilTasksComplete(kNumTasks); | 451 std::vector<int> result = tracker()->WaitUntilTasksComplete(kNumTasks); |
408 EXPECT_EQ(kNumTasks, result.size()); | 452 EXPECT_EQ(kNumTasks, result.size()); |
409 } | 453 } |
410 | 454 |
411 // Tests that posting a bunch of tasks (many more than the number of | 455 // Tests that posting a bunch of tasks (many more than the number of |
412 // worker threads) to two pools simultaneously runs them all twice. | 456 // worker threads) to two pools simultaneously runs them all twice. |
413 // This test is meant to shake out any concurrency issues between | 457 // This test is meant to shake out any concurrency issues between |
414 // pools (like histograms). | 458 // pools (like histograms). |
415 TEST_F(SequencedWorkerPoolTest, LotsOfTasksTwoPools) { | 459 TEST_P(SequencedWorkerPoolTest, LotsOfTasksTwoPools) { |
416 SequencedWorkerPoolOwner pool1(kNumWorkerThreads, "test1"); | 460 SequencedWorkerPoolOwner pool1(kNumWorkerThreads, "test1"); |
417 SequencedWorkerPoolOwner pool2(kNumWorkerThreads, "test2"); | 461 SequencedWorkerPoolOwner pool2(kNumWorkerThreads, "test2"); |
418 | 462 |
419 base::Closure slow_task = base::Bind(&TestTracker::SlowTask, tracker(), 0); | 463 base::Closure slow_task = base::Bind(&TestTracker::SlowTask, tracker(), 0); |
420 pool1.pool()->PostWorkerTask(FROM_HERE, slow_task); | 464 pool1.pool()->PostWorkerTask(FROM_HERE, slow_task); |
421 pool2.pool()->PostWorkerTask(FROM_HERE, slow_task); | 465 pool2.pool()->PostWorkerTask(FROM_HERE, slow_task); |
422 | 466 |
423 const size_t kNumTasks = 20; | 467 const size_t kNumTasks = 20; |
424 for (size_t i = 1; i < kNumTasks; i++) { | 468 for (size_t i = 1; i < kNumTasks; i++) { |
425 base::Closure fast_task = | 469 base::Closure fast_task = |
426 base::Bind(&TestTracker::FastTask, tracker(), i); | 470 base::Bind(&TestTracker::FastTask, tracker(), i); |
427 pool1.pool()->PostWorkerTask(FROM_HERE, fast_task); | 471 pool1.pool()->PostWorkerTask(FROM_HERE, fast_task); |
428 pool2.pool()->PostWorkerTask(FROM_HERE, fast_task); | 472 pool2.pool()->PostWorkerTask(FROM_HERE, fast_task); |
429 } | 473 } |
430 | 474 |
431 std::vector<int> result = | 475 std::vector<int> result = |
432 tracker()->WaitUntilTasksComplete(2*kNumTasks); | 476 tracker()->WaitUntilTasksComplete(2*kNumTasks); |
433 EXPECT_EQ(2 * kNumTasks, result.size()); | 477 EXPECT_EQ(2 * kNumTasks, result.size()); |
434 } | 478 } |
435 | 479 |
436 // Test that tasks with the same sequence token are executed in order but don't | 480 // Test that tasks with the same sequence token are executed in order but don't |
437 // affect other tasks. | 481 // affect other tasks. |
438 TEST_F(SequencedWorkerPoolTest, Sequence) { | 482 TEST_P(SequencedWorkerPoolTest, Sequence) { |
439 // Fill all the worker threads except one. | 483 // Fill all the worker threads except one. |
440 const size_t kNumBackgroundTasks = kNumWorkerThreads - 1; | 484 const size_t kNumBackgroundTasks = kNumWorkerThreads - 1; |
441 ThreadBlocker background_blocker; | 485 ThreadBlocker background_blocker; |
442 for (size_t i = 0; i < kNumBackgroundTasks; i++) { | 486 for (size_t i = 0; i < kNumBackgroundTasks; i++) { |
443 pool()->PostWorkerTask(FROM_HERE, | 487 pool()->PostWorkerTask(FROM_HERE, |
444 base::Bind(&TestTracker::BlockTask, | 488 base::Bind(&TestTracker::BlockTask, |
445 tracker(), i, &background_blocker)); | 489 tracker(), i, &background_blocker)); |
446 } | 490 } |
447 tracker()->WaitUntilTasksBlocked(kNumBackgroundTasks); | 491 tracker()->WaitUntilTasksBlocked(kNumBackgroundTasks); |
448 | 492 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 // Allow the first task of token1 to complete. This should run the second. | 533 // Allow the first task of token1 to complete. This should run the second. |
490 blocker.Unblock(1); | 534 blocker.Unblock(1); |
491 result = tracker()->WaitUntilTasksComplete(kNumBackgroundTasks + 4); | 535 result = tracker()->WaitUntilTasksComplete(kNumBackgroundTasks + 4); |
492 ASSERT_EQ(kNumBackgroundTasks + 4, result.size()); | 536 ASSERT_EQ(kNumBackgroundTasks + 4, result.size()); |
493 EXPECT_EQ(100, result[result.size() - 2]); | 537 EXPECT_EQ(100, result[result.size() - 2]); |
494 EXPECT_EQ(101, result[result.size() - 1]); | 538 EXPECT_EQ(101, result[result.size() - 1]); |
495 } | 539 } |
496 | 540 |
497 // Tests that any tasks posted after Shutdown are ignored. | 541 // Tests that any tasks posted after Shutdown are ignored. |
498 // Disabled for flakiness. See http://crbug.com/166451. | 542 // Disabled for flakiness. See http://crbug.com/166451. |
499 TEST_F(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) { | 543 TEST_P(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) { |
500 // Start tasks to take all the threads and block them. | 544 // Start tasks to take all the threads and block them. |
501 EnsureAllWorkersCreated(); | 545 EnsureAllWorkersCreated(); |
502 ThreadBlocker blocker; | 546 ThreadBlocker blocker; |
503 for (size_t i = 0; i < kNumWorkerThreads; i++) { | 547 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
504 pool()->PostWorkerTask(FROM_HERE, | 548 pool()->PostWorkerTask(FROM_HERE, |
505 base::Bind(&TestTracker::BlockTask, | 549 base::Bind(&TestTracker::BlockTask, |
506 tracker(), i, &blocker)); | 550 tracker(), i, &blocker)); |
507 } | 551 } |
508 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); | 552 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
509 | 553 |
(...skipping 26 matching lines...) Expand all Loading... |
536 base::Bind(&TestTracker::FastTask, tracker(), 101), | 580 base::Bind(&TestTracker::FastTask, tracker(), 101), |
537 SequencedWorkerPool::SKIP_ON_SHUTDOWN)); | 581 SequencedWorkerPool::SKIP_ON_SHUTDOWN)); |
538 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( | 582 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( |
539 FROM_HERE, | 583 FROM_HERE, |
540 base::Bind(&TestTracker::FastTask, tracker(), 102), | 584 base::Bind(&TestTracker::FastTask, tracker(), 102), |
541 SequencedWorkerPool::BLOCK_SHUTDOWN)); | 585 SequencedWorkerPool::BLOCK_SHUTDOWN)); |
542 | 586 |
543 ASSERT_EQ(old_has_work_call_count, has_work_call_count()); | 587 ASSERT_EQ(old_has_work_call_count, has_work_call_count()); |
544 } | 588 } |
545 | 589 |
546 TEST_F(SequencedWorkerPoolTest, AllowsAfterShutdown) { | 590 TEST_P(SequencedWorkerPoolTest, AllowsAfterShutdown) { |
| 591 // TaskScheduler supports posting new BLOCK_SHUTDOWN tasks during shutdown |
| 592 // (see TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown). However, |
| 593 // since it doesn't provide a way to run a callback from inside its Shutdown() |
| 594 // method, it would be hard to make this test work with redirection enabled. |
| 595 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 596 return; |
| 597 |
547 // Test that <n> new blocking tasks are allowed provided they're posted | 598 // Test that <n> new blocking tasks are allowed provided they're posted |
548 // by a running tasks. | 599 // by a running tasks. |
549 EnsureAllWorkersCreated(); | 600 EnsureAllWorkersCreated(); |
550 ThreadBlocker blocker; | 601 ThreadBlocker blocker; |
551 | 602 |
552 // Start tasks to take all the threads and block them. | 603 // Start tasks to take all the threads and block them. |
553 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); | 604 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); |
554 for (int i = 0; i < kNumBlockTasks; ++i) { | 605 for (int i = 0; i < kNumBlockTasks; ++i) { |
555 EXPECT_TRUE(pool()->PostWorkerTask( | 606 EXPECT_TRUE(pool()->PostWorkerTask( |
556 FROM_HERE, | 607 FROM_HERE, |
(...skipping 25 matching lines...) Expand all Loading... |
582 // Ensure that the correct number of tasks actually got run. | 633 // Ensure that the correct number of tasks actually got run. |
583 tracker()->WaitUntilTasksComplete(static_cast<size_t>( | 634 tracker()->WaitUntilTasksComplete(static_cast<size_t>( |
584 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow)); | 635 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow)); |
585 | 636 |
586 // Clean up the task IDs we added and go home. | 637 // Clean up the task IDs we added and go home. |
587 tracker()->ClearCompleteSequence(); | 638 tracker()->ClearCompleteSequence(); |
588 } | 639 } |
589 | 640 |
590 // Tests that blocking tasks can still be posted during shutdown, as long as | 641 // Tests that blocking tasks can still be posted during shutdown, as long as |
591 // the task is not being posted within the context of a running task. | 642 // the task is not being posted within the context of a running task. |
592 TEST_F(SequencedWorkerPoolTest, | 643 TEST_P(SequencedWorkerPoolTest, |
593 AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) { | 644 AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) { |
| 645 // TaskScheduler supports posting new BLOCK_SHUTDOWN tasks during shutdown |
| 646 // (see TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown). However, |
| 647 // since it doesn't provide a way to run a callback from inside its Shutdown() |
| 648 // method, it would be hard to make this test work with redirection enabled. |
| 649 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 650 return; |
| 651 |
594 EnsureAllWorkersCreated(); | 652 EnsureAllWorkersCreated(); |
595 ThreadBlocker blocker; | 653 ThreadBlocker blocker; |
596 | 654 |
597 // Start tasks to take all the threads and block them. | 655 // Start tasks to take all the threads and block them. |
598 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); | 656 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); |
599 for (int i = 0; i < kNumBlockTasks; ++i) { | 657 for (int i = 0; i < kNumBlockTasks; ++i) { |
600 EXPECT_TRUE(pool()->PostWorkerTask( | 658 EXPECT_TRUE(pool()->PostWorkerTask( |
601 FROM_HERE, | 659 FROM_HERE, |
602 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); | 660 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); |
603 } | 661 } |
604 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); | 662 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
605 | 663 |
606 // Setup to open the floodgates from within Shutdown(). | 664 // Setup to open the floodgates from within Shutdown(). |
607 SetWillWaitForShutdownCallback( | 665 SetWillWaitForShutdownCallback( |
608 base::Bind(&TestTracker::PostBlockingTaskThenUnblockThreads, | 666 base::Bind(&TestTracker::PostBlockingTaskThenUnblockThreads, |
609 scoped_refptr<TestTracker>(tracker()), pool(), &blocker, | 667 scoped_refptr<TestTracker>(tracker()), pool(), &blocker, |
610 kNumWorkerThreads)); | 668 kNumWorkerThreads)); |
611 pool()->Shutdown(kNumWorkerThreads + 1); | 669 pool()->Shutdown(kNumWorkerThreads + 1); |
612 | 670 |
613 // Ensure that the correct number of tasks actually got run. | 671 // Ensure that the correct number of tasks actually got run. |
614 tracker()->WaitUntilTasksComplete(static_cast<size_t>(kNumWorkerThreads + 1)); | 672 tracker()->WaitUntilTasksComplete(static_cast<size_t>(kNumWorkerThreads + 1)); |
615 tracker()->ClearCompleteSequence(); | 673 tracker()->ClearCompleteSequence(); |
616 } | 674 } |
617 | 675 |
618 // Tests that unrun tasks are discarded properly according to their shutdown | 676 // Tests that unrun tasks are discarded properly according to their shutdown |
619 // mode. | 677 // mode. |
620 TEST_F(SequencedWorkerPoolTest, DiscardOnShutdown) { | 678 TEST_P(SequencedWorkerPoolTest, DiscardOnShutdown) { |
| 679 // Since TaskScheduler doesn't provide a way to run a callback from inside its |
| 680 // Shutdown() method, it would be hard to make this test work with redirection |
| 681 // enabled. |
| 682 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 683 return; |
| 684 |
621 // Start tasks to take all the threads and block them. | 685 // Start tasks to take all the threads and block them. |
622 EnsureAllWorkersCreated(); | 686 EnsureAllWorkersCreated(); |
623 ThreadBlocker blocker; | 687 ThreadBlocker blocker; |
624 for (size_t i = 0; i < kNumWorkerThreads; i++) { | 688 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
625 pool()->PostWorkerTask(FROM_HERE, | 689 pool()->PostWorkerTask(FROM_HERE, |
626 base::Bind(&TestTracker::BlockTask, | 690 base::Bind(&TestTracker::BlockTask, |
627 tracker(), i, &blocker)); | 691 tracker(), i, &blocker)); |
628 } | 692 } |
629 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); | 693 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
630 | 694 |
(...skipping 23 matching lines...) Expand all Loading... |
654 | 718 |
655 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN | 719 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN |
656 // one, in no particular order. | 720 // one, in no particular order. |
657 ASSERT_EQ(kNumWorkerThreads + 1, result.size()); | 721 ASSERT_EQ(kNumWorkerThreads + 1, result.size()); |
658 for (size_t i = 0; i < kNumWorkerThreads; i++) | 722 for (size_t i = 0; i < kNumWorkerThreads; i++) |
659 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); | 723 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); |
660 EXPECT_TRUE(ContainsValue(result, 102)); | 724 EXPECT_TRUE(ContainsValue(result, 102)); |
661 } | 725 } |
662 | 726 |
663 // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown. | 727 // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown. |
664 TEST_F(SequencedWorkerPoolTest, ContinueOnShutdown) { | 728 TEST_P(SequencedWorkerPoolTest, ContinueOnShutdown) { |
665 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior( | 729 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior( |
666 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); | 730 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); |
667 scoped_refptr<SequencedTaskRunner> sequenced_runner( | 731 scoped_refptr<SequencedTaskRunner> sequenced_runner( |
668 pool()->GetSequencedTaskRunnerWithShutdownBehavior( | 732 pool()->GetSequencedTaskRunnerWithShutdownBehavior( |
669 pool()->GetSequenceToken(), | 733 pool()->GetSequenceToken(), |
670 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); | 734 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); |
671 EnsureAllWorkersCreated(); | 735 EnsureAllWorkersCreated(); |
672 ThreadBlocker blocker; | 736 ThreadBlocker blocker; |
673 pool()->PostWorkerTaskWithShutdownBehavior( | 737 pool()->PostWorkerTaskWithShutdownBehavior( |
674 FROM_HERE, | 738 FROM_HERE, |
675 base::Bind(&TestTracker::BlockTask, | 739 base::Bind(&TestTracker::BlockTask, |
676 tracker(), 0, &blocker), | 740 tracker(), 0, &blocker), |
677 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); | 741 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); |
678 runner->PostTask( | 742 runner->PostTask( |
679 FROM_HERE, | 743 FROM_HERE, |
680 base::Bind(&TestTracker::BlockTask, | 744 base::Bind(&TestTracker::BlockTask, |
681 tracker(), 1, &blocker)); | 745 tracker(), 1, &blocker)); |
682 sequenced_runner->PostTask( | 746 sequenced_runner->PostTask( |
683 FROM_HERE, | 747 FROM_HERE, |
684 base::Bind(&TestTracker::BlockTask, | 748 base::Bind(&TestTracker::BlockTask, |
685 tracker(), 2, &blocker)); | 749 tracker(), 2, &blocker)); |
686 | 750 |
687 tracker()->WaitUntilTasksBlocked(3); | 751 tracker()->WaitUntilTasksBlocked(3); |
688 | 752 |
689 // This should not block. If this test hangs, it means it failed. | 753 // Shutting down the pool should not be blocked by CONTINUE_ON_SHUTDOWN tasks. |
| 754 // If this test hangs, it means it failed. |
| 755 // Note: This is a no-op when redirection to the TaskScheduler is enabled. |
690 pool()->Shutdown(); | 756 pool()->Shutdown(); |
691 | 757 |
| 758 // Shutting down the TaskScheduler should not be blocked by |
| 759 // CONTINUE_ON_SHUTDOWN tasks. |
| 760 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 761 TaskScheduler::GetInstance()->Shutdown(); |
| 762 |
692 // The task should not have completed yet. | 763 // The task should not have completed yet. |
693 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size()); | 764 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size()); |
694 | 765 |
695 // Posting more tasks should fail. | 766 // Posting more tasks should fail. |
696 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( | 767 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( |
697 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0), | 768 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0), |
698 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); | 769 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); |
699 EXPECT_FALSE(runner->PostTask( | 770 EXPECT_FALSE(runner->PostTask( |
700 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); | 771 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); |
701 EXPECT_FALSE(sequenced_runner->PostTask( | 772 EXPECT_FALSE(sequenced_runner->PostTask( |
702 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); | 773 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); |
703 | 774 |
704 // Continue the background thread and make sure the tasks can complete. | 775 // Continue the background thread and make sure the tasks can complete. |
705 blocker.Unblock(3); | 776 blocker.Unblock(3); |
706 std::vector<int> result = tracker()->WaitUntilTasksComplete(3); | 777 std::vector<int> result = tracker()->WaitUntilTasksComplete(3); |
707 EXPECT_EQ(3u, result.size()); | 778 EXPECT_EQ(3u, result.size()); |
708 } | 779 } |
709 | 780 |
710 // Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown | 781 // Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown |
711 // until they stop, but tasks not yet started do not. | 782 // until they stop, but tasks not yet started do not. |
712 TEST_F(SequencedWorkerPoolTest, SkipOnShutdown) { | 783 TEST_P(SequencedWorkerPoolTest, SkipOnShutdown) { |
| 784 // Since TaskScheduler doesn't provide a way to run a callback from inside its |
| 785 // Shutdown() method, it would be hard to make this test work with redirection |
| 786 // enabled. |
| 787 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 788 return; |
| 789 |
713 // Start tasks to take all the threads and block them. | 790 // Start tasks to take all the threads and block them. |
714 EnsureAllWorkersCreated(); | 791 EnsureAllWorkersCreated(); |
715 ThreadBlocker blocker; | 792 ThreadBlocker blocker; |
716 | 793 |
717 // Now block all the threads with SKIP_ON_SHUTDOWN. Shutdown() should not | 794 // Now block all the threads with SKIP_ON_SHUTDOWN. Shutdown() should not |
718 // return until these tasks have completed. | 795 // return until these tasks have completed. |
719 for (size_t i = 0; i < kNumWorkerThreads; i++) { | 796 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
720 pool()->PostWorkerTaskWithShutdownBehavior( | 797 pool()->PostWorkerTaskWithShutdownBehavior( |
721 FROM_HERE, | 798 FROM_HERE, |
722 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker), | 799 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker), |
(...skipping 30 matching lines...) Expand all Loading... |
753 // allowed to complete. No additional non-blocking tasks should have been | 830 // allowed to complete. No additional non-blocking tasks should have been |
754 // started. | 831 // started. |
755 ASSERT_EQ(kNumWorkerThreads, result.size()); | 832 ASSERT_EQ(kNumWorkerThreads, result.size()); |
756 for (size_t i = 0; i < kNumWorkerThreads; i++) | 833 for (size_t i = 0; i < kNumWorkerThreads; i++) |
757 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); | 834 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); |
758 } | 835 } |
759 | 836 |
760 // Ensure all worker threads are created, and then trigger a spurious | 837 // Ensure all worker threads are created, and then trigger a spurious |
761 // work signal. This shouldn't cause any other work signals to be | 838 // work signal. This shouldn't cause any other work signals to be |
762 // triggered. This is a regression test for http://crbug.com/117469. | 839 // triggered. This is a regression test for http://crbug.com/117469. |
763 TEST_F(SequencedWorkerPoolTest, SpuriousWorkSignal) { | 840 TEST_P(SequencedWorkerPoolTest, SpuriousWorkSignal) { |
| 841 // This test doesn't apply when tasks are redirected to the TaskScheduler. |
| 842 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 843 return; |
| 844 |
764 EnsureAllWorkersCreated(); | 845 EnsureAllWorkersCreated(); |
765 int old_has_work_call_count = has_work_call_count(); | 846 int old_has_work_call_count = has_work_call_count(); |
766 pool()->SignalHasWorkForTesting(); | 847 pool()->SignalHasWorkForTesting(); |
767 // This is inherently racy, but can only produce false positives. | 848 // This is inherently racy, but can only produce false positives. |
768 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); | 849 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); |
769 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count()); | 850 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count()); |
770 } | 851 } |
771 | 852 |
772 void IsRunningOnCurrentThreadTask( | 853 void IsRunningOnCurrentThreadTask( |
773 SequencedWorkerPool::SequenceToken test_positive_token, | 854 SequencedWorkerPool::SequenceToken test_positive_token, |
774 SequencedWorkerPool::SequenceToken test_negative_token, | 855 SequencedWorkerPool::SequenceToken test_negative_token, |
775 SequencedWorkerPool* pool, | 856 SequencedWorkerPool* pool, |
776 SequencedWorkerPool* unused_pool) { | 857 SequencedWorkerPool* unused_pool, |
| 858 SequencedWorkerPoolRedirection redirection) { |
777 EXPECT_TRUE(pool->RunsTasksOnCurrentThread()); | 859 EXPECT_TRUE(pool->RunsTasksOnCurrentThread()); |
778 EXPECT_TRUE(pool->IsRunningSequenceOnCurrentThread(test_positive_token)); | 860 EXPECT_TRUE(pool->IsRunningSequenceOnCurrentThread(test_positive_token)); |
779 EXPECT_FALSE(pool->IsRunningSequenceOnCurrentThread(test_negative_token)); | 861 |
780 EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread()); | 862 if (redirection == SequencedWorkerPoolRedirection::NONE) { |
781 EXPECT_FALSE( | 863 // Tasks posted to different pools may run on the same threads when |
782 unused_pool->IsRunningSequenceOnCurrentThread(test_positive_token)); | 864 // redirection to the TaskScheduler is enabled. |
783 EXPECT_FALSE( | 865 EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread()); |
784 unused_pool->IsRunningSequenceOnCurrentThread(test_negative_token)); | 866 |
| 867 // TODO(gab): When redirection to the TaskScheduler is enabled, |
| 868 // IsRunningSequenceOnCurrentThread() returns true if a task bound to the |
| 869 // provided sequence token *could* run on the current thread. Once the |
| 870 // method is fixed to return true only when called from a thread that is |
| 871 // *currently running* a task bound to the provided sequence token, move |
| 872 // these tests out of the conditional. |
| 873 EXPECT_FALSE(pool->IsRunningSequenceOnCurrentThread(test_negative_token)); |
| 874 EXPECT_FALSE( |
| 875 unused_pool->IsRunningSequenceOnCurrentThread(test_positive_token)); |
| 876 EXPECT_FALSE( |
| 877 unused_pool->IsRunningSequenceOnCurrentThread(test_negative_token)); |
| 878 } |
785 } | 879 } |
786 | 880 |
787 // Verify correctness of the IsRunningSequenceOnCurrentThread method. | 881 // Verify correctness of the IsRunningSequenceOnCurrentThread method. |
788 TEST_F(SequencedWorkerPoolTest, IsRunningOnCurrentThread) { | 882 TEST_P(SequencedWorkerPoolTest, IsRunningOnCurrentThread) { |
789 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); | 883 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); |
790 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); | 884 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); |
791 SequencedWorkerPool::SequenceToken unsequenced_token; | 885 SequencedWorkerPool::SequenceToken unsequenced_token; |
792 | 886 |
793 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool"); | 887 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool"); |
794 | 888 |
795 EXPECT_FALSE(pool()->RunsTasksOnCurrentThread()); | 889 EXPECT_FALSE(pool()->RunsTasksOnCurrentThread()); |
796 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token1)); | 890 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token1)); |
797 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token2)); | 891 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token2)); |
798 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(unsequenced_token)); | 892 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(unsequenced_token)); |
799 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread()); | 893 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread()); |
800 EXPECT_FALSE( | 894 EXPECT_FALSE( |
801 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token1)); | 895 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token1)); |
802 EXPECT_FALSE( | 896 EXPECT_FALSE( |
803 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token2)); | 897 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token2)); |
804 EXPECT_FALSE(unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread( | 898 EXPECT_FALSE(unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread( |
805 unsequenced_token)); | 899 unsequenced_token)); |
806 | 900 |
807 pool()->PostSequencedWorkerTask( | 901 pool()->PostSequencedWorkerTask( |
808 token1, FROM_HERE, | 902 token1, FROM_HERE, |
809 base::Bind(&IsRunningOnCurrentThreadTask, token1, token2, | 903 base::Bind(&IsRunningOnCurrentThreadTask, token1, token2, |
810 base::RetainedRef(pool()), | 904 base::RetainedRef(pool()), |
811 base::RetainedRef(unused_pool_owner.pool()))); | 905 base::RetainedRef(unused_pool_owner.pool()), GetParam())); |
812 pool()->PostSequencedWorkerTask( | 906 pool()->PostSequencedWorkerTask( |
813 token2, FROM_HERE, | 907 token2, FROM_HERE, |
814 base::Bind(&IsRunningOnCurrentThreadTask, token2, unsequenced_token, | 908 base::Bind(&IsRunningOnCurrentThreadTask, token2, unsequenced_token, |
815 base::RetainedRef(pool()), | 909 base::RetainedRef(pool()), |
816 base::RetainedRef(unused_pool_owner.pool()))); | 910 base::RetainedRef(unused_pool_owner.pool()), GetParam())); |
817 pool()->PostWorkerTask( | 911 pool()->PostWorkerTask( |
818 FROM_HERE, base::Bind(&IsRunningOnCurrentThreadTask, unsequenced_token, | 912 FROM_HERE, |
819 token1, base::RetainedRef(pool()), | 913 base::Bind(&IsRunningOnCurrentThreadTask, unsequenced_token, token1, |
820 base::RetainedRef(unused_pool_owner.pool()))); | 914 base::RetainedRef(pool()), |
| 915 base::RetainedRef(unused_pool_owner.pool()), GetParam())); |
821 } | 916 } |
822 | 917 |
823 // Checks that tasks are destroyed in the right context during shutdown. If a | 918 // Checks that tasks are destroyed in the right context during shutdown. If a |
824 // task is destroyed while SequencedWorkerPool's global lock is held, | 919 // task is destroyed while SequencedWorkerPool's global lock is held, |
825 // SequencedWorkerPool might deadlock. | 920 // SequencedWorkerPool might deadlock. |
826 TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) { | 921 TEST_P(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) { |
| 922 // Since the TaskScheduler doesn't delete pending tasks on shutdown, this test |
| 923 // doesn't apply when tasks are redirected to the TaskScheduler. |
| 924 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 925 return; |
| 926 |
827 for (int i = 0; i < 4; ++i) { | 927 for (int i = 0; i < 4; ++i) { |
828 scoped_refptr<DestructionDeadlockChecker> checker( | 928 scoped_refptr<DestructionDeadlockChecker> checker( |
829 new DestructionDeadlockChecker(pool())); | 929 new DestructionDeadlockChecker(pool())); |
830 tracker()->PostRepostingTask(pool(), checker); | 930 tracker()->PostRepostingTask(pool(), checker); |
831 } | 931 } |
832 | 932 |
833 // Shutting down the pool should destroy the DestructionDeadlockCheckers, | 933 // Shutting down the pool should destroy the DestructionDeadlockCheckers, |
834 // which in turn should not deadlock in their destructors. | 934 // which in turn should not deadlock in their destructors. |
835 pool()->Shutdown(); | 935 pool()->Shutdown(); |
836 } | 936 } |
837 | 937 |
838 // Similar to the test AvoidsDeadlockOnShutdown, but there are now also | 938 // Similar to the test AvoidsDeadlockOnShutdown, but there are now also |
839 // sequenced, blocking tasks in the queue during shutdown. | 939 // sequenced, blocking tasks in the queue during shutdown. |
840 TEST_F(SequencedWorkerPoolTest, | 940 TEST_P(SequencedWorkerPoolTest, |
841 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) { | 941 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) { |
| 942 // Since the TaskScheduler doesn't delete pending tasks on shutdown, this test |
| 943 // doesn't apply when tasks are redirected to the TaskScheduler. |
| 944 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 945 return; |
| 946 |
842 const std::string sequence_token_name("name"); | 947 const std::string sequence_token_name("name"); |
843 for (int i = 0; i < 4; ++i) { | 948 for (int i = 0; i < 4; ++i) { |
844 scoped_refptr<DestructionDeadlockChecker> checker( | 949 scoped_refptr<DestructionDeadlockChecker> checker( |
845 new DestructionDeadlockChecker(pool())); | 950 new DestructionDeadlockChecker(pool())); |
846 tracker()->PostRepostingTask(pool(), checker); | 951 tracker()->PostRepostingTask(pool(), checker); |
847 | 952 |
848 SequencedWorkerPool::SequenceToken token1 = | 953 SequencedWorkerPool::SequenceToken token1 = |
849 pool()->GetNamedSequenceToken(sequence_token_name); | 954 pool()->GetNamedSequenceToken(sequence_token_name); |
850 tracker()->PostRepostingBlockingTask(pool(), token1); | 955 tracker()->PostRepostingBlockingTask(pool(), token1); |
851 } | 956 } |
852 | 957 |
853 // Shutting down the pool should destroy the DestructionDeadlockCheckers, | 958 // Shutting down the pool should destroy the DestructionDeadlockCheckers, |
854 // which in turn should not deadlock in their destructors. | 959 // which in turn should not deadlock in their destructors. |
855 pool()->Shutdown(); | 960 pool()->Shutdown(); |
856 } | 961 } |
857 | 962 |
858 // Verify that FlushForTesting works as intended. | 963 // Verify that FlushForTesting works as intended. |
859 TEST_F(SequencedWorkerPoolTest, FlushForTesting) { | 964 TEST_P(SequencedWorkerPoolTest, FlushForTesting) { |
| 965 // FlushForTesting cannot be called when tasks are redirected to the |
| 966 // TaskScheduler. |
| 967 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 968 return; |
| 969 |
860 // Should be fine to call on a new instance. | 970 // Should be fine to call on a new instance. |
861 pool()->FlushForTesting(); | 971 pool()->FlushForTesting(); |
862 | 972 |
863 // Queue up a bunch of work, including a long delayed task and | 973 // Queue up a bunch of work, including a long delayed task and |
864 // a task that produces additional tasks as an artifact. | 974 // a task that produces additional tasks as an artifact. |
865 pool()->PostDelayedWorkerTask( | 975 pool()->PostDelayedWorkerTask( |
866 FROM_HERE, | 976 FROM_HERE, |
867 base::Bind(&TestTracker::FastTask, tracker(), 0), | 977 base::Bind(&TestTracker::FastTask, tracker(), 0), |
868 TimeDelta::FromMinutes(5)); | 978 TimeDelta::FromMinutes(5)); |
869 pool()->PostWorkerTask(FROM_HERE, | 979 pool()->PostWorkerTask(FROM_HERE, |
(...skipping 18 matching lines...) Expand all Loading... |
888 // Should be fine to call on an idle instance with all threads created, and | 998 // Should be fine to call on an idle instance with all threads created, and |
889 // spamming the method shouldn't deadlock or confuse the class. | 999 // spamming the method shouldn't deadlock or confuse the class. |
890 pool()->FlushForTesting(); | 1000 pool()->FlushForTesting(); |
891 pool()->FlushForTesting(); | 1001 pool()->FlushForTesting(); |
892 | 1002 |
893 // Should be fine to call after shutdown too. | 1003 // Should be fine to call after shutdown too. |
894 pool()->Shutdown(); | 1004 pool()->Shutdown(); |
895 pool()->FlushForTesting(); | 1005 pool()->FlushForTesting(); |
896 } | 1006 } |
897 | 1007 |
| 1008 INSTANTIATE_TEST_CASE_P( |
| 1009 NoRedirection, |
| 1010 SequencedWorkerPoolTest, |
| 1011 ::testing::Values(SequencedWorkerPoolRedirection::NONE)); |
| 1012 INSTANTIATE_TEST_CASE_P( |
| 1013 RedirectionToTaskScheduler, |
| 1014 SequencedWorkerPoolTest, |
| 1015 ::testing::Values(SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)); |
| 1016 |
898 namespace { | 1017 namespace { |
899 | 1018 |
900 void CheckWorkerPoolAndSequenceToken( | 1019 void CheckWorkerPoolAndSequenceToken( |
901 const scoped_refptr<SequencedWorkerPool>& expected_pool, | 1020 const scoped_refptr<SequencedWorkerPool>& expected_pool, |
902 SequencedWorkerPool::SequenceToken expected_token) { | 1021 SequencedWorkerPool::SequenceToken expected_token) { |
903 SequencedWorkerPool::SequenceToken token = | 1022 SequencedWorkerPool::SequenceToken token = |
904 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); | 1023 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); |
905 EXPECT_EQ(expected_token.ToString(), token.ToString()); | 1024 EXPECT_EQ(expected_token.ToString(), token.ToString()); |
906 | 1025 |
907 scoped_refptr<SequencedWorkerPool> pool = | 1026 scoped_refptr<SequencedWorkerPool> pool = |
908 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); | 1027 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); |
909 EXPECT_EQ(expected_pool, pool); | 1028 EXPECT_EQ(expected_pool, pool); |
910 } | 1029 } |
911 | 1030 |
912 } // namespace | 1031 } // namespace |
913 | 1032 |
914 TEST_F(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) { | 1033 TEST_P(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) { |
| 1034 // SequencedWorkerPool::GetSequenceTokenForCurrentThread() isn't supported |
| 1035 // when tasks are redirected to the TaskScheduler. It will never be supported |
| 1036 // since its only uses are in SequencedTaskRunnerHandle and |
| 1037 // SequenceCheckerImpl which don't need it when redirection is enabled. |
| 1038 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 1039 return; |
| 1040 |
915 EnsureAllWorkersCreated(); | 1041 EnsureAllWorkersCreated(); |
916 | 1042 |
917 // The current thread should have neither a worker pool nor a sequence token. | 1043 // The current thread should have neither a worker pool nor a sequence token. |
918 SequencedWorkerPool::SequenceToken local_token = | 1044 SequencedWorkerPool::SequenceToken local_token = |
919 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); | 1045 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); |
920 scoped_refptr<SequencedWorkerPool> local_pool = | 1046 scoped_refptr<SequencedWorkerPool> local_pool = |
921 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); | 1047 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); |
922 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString(); | 1048 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString(); |
923 EXPECT_FALSE(local_pool); | 1049 EXPECT_FALSE(local_pool); |
924 | 1050 |
925 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); | 1051 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); |
926 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); | 1052 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); |
927 pool()->PostSequencedWorkerTask( | 1053 pool()->PostSequencedWorkerTask( |
928 token1, FROM_HERE, | 1054 token1, FROM_HERE, |
929 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token1)); | 1055 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token1)); |
930 pool()->PostSequencedWorkerTask( | 1056 pool()->PostSequencedWorkerTask( |
931 token2, FROM_HERE, | 1057 token2, FROM_HERE, |
932 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token2)); | 1058 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token2)); |
933 | 1059 |
934 pool()->PostWorkerTask(FROM_HERE, | 1060 pool()->PostWorkerTask(FROM_HERE, |
935 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), | 1061 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), |
936 SequencedWorkerPool::SequenceToken())); | 1062 SequencedWorkerPool::SequenceToken())); |
937 | 1063 |
938 pool()->FlushForTesting(); | 1064 pool()->FlushForTesting(); |
939 } | 1065 } |
940 | 1066 |
941 TEST_F(SequencedWorkerPoolTest, ShutsDownCleanWithContinueOnShutdown) { | 1067 template <SequencedWorkerPoolRedirection redirection> |
942 scoped_refptr<SequencedTaskRunner> task_runner = | |
943 pool()->GetSequencedTaskRunnerWithShutdownBehavior( | |
944 pool()->GetSequenceToken(), | |
945 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); | |
946 | |
947 // Upon test exit, should shut down without hanging. | |
948 pool()->Shutdown(); | |
949 } | |
950 | |
951 class SequencedWorkerPoolTaskRunnerTestDelegate { | 1068 class SequencedWorkerPoolTaskRunnerTestDelegate { |
952 public: | 1069 public: |
953 SequencedWorkerPoolTaskRunnerTestDelegate() {} | 1070 SequencedWorkerPoolTaskRunnerTestDelegate() {} |
954 | 1071 |
955 ~SequencedWorkerPoolTaskRunnerTestDelegate() {} | 1072 ~SequencedWorkerPoolTaskRunnerTestDelegate() {} |
956 | 1073 |
957 void StartTaskRunner() { | 1074 void StartTaskRunner() { |
958 pool_owner_.reset( | 1075 pool_owner_.reset(new SequencedWorkerPoolOwner( |
959 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest")); | 1076 kNumWorkerThreads, "SequencedWorkerPoolTaskRunnerTest")); |
| 1077 |
| 1078 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 1079 StartRedirectionToTaskScheduler(kNumWorkerThreads); |
960 } | 1080 } |
961 | 1081 |
962 scoped_refptr<SequencedWorkerPool> GetTaskRunner() { | 1082 scoped_refptr<SequencedWorkerPool> GetTaskRunner() { |
963 return pool_owner_->pool(); | 1083 return pool_owner_->pool(); |
964 } | 1084 } |
965 | 1085 |
966 void StopTaskRunner() { | 1086 void StopTaskRunner() { |
967 // Make sure all tasks are run before shutting down. Delayed tasks are | 1087 pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks); |
968 // not run, they're simply deleted. | 1088 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) { |
969 pool_owner_->pool()->FlushForTesting(); | 1089 // When redirection to the TaskScheduler is enabled, shutting down the |
970 pool_owner_->pool()->Shutdown(); | 1090 // pool is a no-op. It is necessary to shut down the TaskScheduler to make |
971 // Don't reset |pool_owner_| here, as the test may still hold a | 1091 // sure that all tasks have been executed. |
972 // reference to the pool. | 1092 TaskScheduler::GetInstance()->Shutdown(); |
| 1093 StopRedirectionToTaskScheduler(); |
| 1094 } |
| 1095 // Don't reset |pool_owner_| here, as the test may still hold a reference to |
| 1096 // the pool. |
973 } | 1097 } |
974 | 1098 |
975 private: | 1099 private: |
976 MessageLoop message_loop_; | 1100 MessageLoop message_loop_; |
977 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; | 1101 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; |
978 }; | 1102 }; |
979 | 1103 |
| 1104 INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool, |
| 1105 TaskRunnerTest, |
| 1106 SequencedWorkerPoolTaskRunnerTestDelegate< |
| 1107 SequencedWorkerPoolRedirection::NONE>); |
| 1108 INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool, |
| 1109 TaskRunnerAffinityTest, |
| 1110 SequencedWorkerPoolTaskRunnerTestDelegate< |
| 1111 SequencedWorkerPoolRedirection::NONE>); |
980 INSTANTIATE_TYPED_TEST_CASE_P( | 1112 INSTANTIATE_TYPED_TEST_CASE_P( |
981 SequencedWorkerPool, TaskRunnerTest, | 1113 SequencedWorkerPoolToTaskScheduler, |
982 SequencedWorkerPoolTaskRunnerTestDelegate); | 1114 TaskRunnerTest, |
983 INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool, TaskRunnerAffinityTest, | 1115 SequencedWorkerPoolTaskRunnerTestDelegate< |
984 SequencedWorkerPoolTaskRunnerTestDelegate); | 1116 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); |
| 1117 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1118 SequencedWorkerPoolToTaskScheduler, |
| 1119 TaskRunnerAffinityTest, |
| 1120 SequencedWorkerPoolTaskRunnerTestDelegate< |
| 1121 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); |
985 | 1122 |
| 1123 template <SequencedWorkerPoolRedirection redirection> |
986 class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate { | 1124 class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate { |
987 public: | 1125 public: |
988 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() {} | 1126 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() {} |
989 | 1127 |
990 ~SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() { | 1128 ~SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() { |
991 } | 1129 } |
992 | 1130 |
993 void StartTaskRunner() { | 1131 void StartTaskRunner() { |
994 pool_owner_.reset( | 1132 pool_owner_.reset(new SequencedWorkerPoolOwner( |
995 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest")); | 1133 kNumWorkerThreads, "SequencedWorkerPoolSequencedTaskRunnerTest")); |
996 task_runner_ = pool_owner_->pool()->GetTaskRunnerWithShutdownBehavior( | 1134 task_runner_ = pool_owner_->pool()->GetTaskRunnerWithShutdownBehavior( |
997 SequencedWorkerPool::BLOCK_SHUTDOWN); | 1135 SequencedWorkerPool::BLOCK_SHUTDOWN); |
| 1136 |
| 1137 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 1138 StartRedirectionToTaskScheduler(kNumWorkerThreads); |
998 } | 1139 } |
999 | 1140 |
1000 scoped_refptr<TaskRunner> GetTaskRunner() { | 1141 scoped_refptr<TaskRunner> GetTaskRunner() { |
1001 return task_runner_; | 1142 return task_runner_; |
1002 } | 1143 } |
1003 | 1144 |
1004 void StopTaskRunner() { | 1145 void StopTaskRunner() { |
1005 // Make sure all tasks are run before shutting down. Delayed tasks are | 1146 pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks); |
1006 // not run, they're simply deleted. | 1147 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) { |
1007 pool_owner_->pool()->FlushForTesting(); | 1148 // When redirection to the TaskScheduler is enabled, shutting down the |
1008 pool_owner_->pool()->Shutdown(); | 1149 // pool is a no-op. It is necessary to shut down the TaskScheduler to make |
1009 // Don't reset |pool_owner_| here, as the test may still hold a | 1150 // sure that all tasks have been executed. |
1010 // reference to the pool. | 1151 TaskScheduler::GetInstance()->Shutdown(); |
| 1152 StopRedirectionToTaskScheduler(); |
| 1153 } |
| 1154 // Don't reset |pool_owner_| here, as the test may still hold a reference to |
| 1155 // the pool. |
1011 } | 1156 } |
1012 | 1157 |
1013 private: | 1158 private: |
1014 MessageLoop message_loop_; | 1159 MessageLoop message_loop_; |
1015 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; | 1160 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; |
1016 scoped_refptr<TaskRunner> task_runner_; | 1161 scoped_refptr<TaskRunner> task_runner_; |
1017 }; | 1162 }; |
1018 | 1163 |
1019 INSTANTIATE_TYPED_TEST_CASE_P( | 1164 INSTANTIATE_TYPED_TEST_CASE_P( |
1020 SequencedWorkerPoolTaskRunner, TaskRunnerTest, | 1165 SequencedWorkerPoolTaskRunner, |
1021 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate); | 1166 TaskRunnerTest, |
| 1167 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate< |
| 1168 SequencedWorkerPoolRedirection::NONE>); |
1022 INSTANTIATE_TYPED_TEST_CASE_P( | 1169 INSTANTIATE_TYPED_TEST_CASE_P( |
1023 SequencedWorkerPoolTaskRunner, TaskRunnerAffinityTest, | 1170 SequencedWorkerPoolTaskRunner, |
1024 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate); | 1171 TaskRunnerAffinityTest, |
| 1172 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate< |
| 1173 SequencedWorkerPoolRedirection::NONE>); |
| 1174 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1175 SequencedWorkerPoolTaskRunnerToTaskScheduler, |
| 1176 TaskRunnerTest, |
| 1177 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate< |
| 1178 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); |
| 1179 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1180 SequencedWorkerPoolTaskRunnerToTaskScheduler, |
| 1181 TaskRunnerAffinityTest, |
| 1182 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate< |
| 1183 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); |
1025 | 1184 |
| 1185 template <SequencedWorkerPoolRedirection redirection> |
1026 class SequencedWorkerPoolSequencedTaskRunnerTestDelegate { | 1186 class SequencedWorkerPoolSequencedTaskRunnerTestDelegate { |
1027 public: | 1187 public: |
1028 SequencedWorkerPoolSequencedTaskRunnerTestDelegate() {} | 1188 SequencedWorkerPoolSequencedTaskRunnerTestDelegate() {} |
1029 | 1189 |
1030 ~SequencedWorkerPoolSequencedTaskRunnerTestDelegate() { | 1190 ~SequencedWorkerPoolSequencedTaskRunnerTestDelegate() { |
1031 } | 1191 } |
1032 | 1192 |
1033 void StartTaskRunner() { | 1193 void StartTaskRunner() { |
1034 pool_owner_.reset(new SequencedWorkerPoolOwner( | 1194 pool_owner_.reset(new SequencedWorkerPoolOwner( |
1035 10, "SequencedWorkerPoolSequencedTaskRunnerTest")); | 1195 kNumWorkerThreads, "SequencedWorkerPoolSequencedTaskRunnerTest")); |
1036 task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner( | 1196 task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner( |
1037 pool_owner_->pool()->GetSequenceToken()); | 1197 pool_owner_->pool()->GetSequenceToken()); |
| 1198 |
| 1199 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) |
| 1200 StartRedirectionToTaskScheduler(kNumWorkerThreads); |
1038 } | 1201 } |
1039 | 1202 |
1040 scoped_refptr<SequencedTaskRunner> GetTaskRunner() { | 1203 scoped_refptr<SequencedTaskRunner> GetTaskRunner() { |
1041 return task_runner_; | 1204 return task_runner_; |
1042 } | 1205 } |
1043 | 1206 |
1044 void StopTaskRunner() { | 1207 void StopTaskRunner() { |
1045 // Make sure all tasks are run before shutting down. Delayed tasks are | 1208 pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks); |
1046 // not run, they're simply deleted. | 1209 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) { |
1047 pool_owner_->pool()->FlushForTesting(); | 1210 // When redirection to the TaskScheduler is enabled, shutting down the |
1048 pool_owner_->pool()->Shutdown(); | 1211 // pool is a no-op. It is necessary to shut down the TaskScheduler to make |
1049 // Don't reset |pool_owner_| here, as the test may still hold a | 1212 // sure that all tasks have been executed. |
1050 // reference to the pool. | 1213 TaskScheduler::GetInstance()->Shutdown(); |
| 1214 StopRedirectionToTaskScheduler(); |
| 1215 } |
| 1216 // Don't reset |pool_owner_| here, as the test may still hold a reference to |
| 1217 // the pool. |
1051 } | 1218 } |
1052 | 1219 |
1053 private: | 1220 private: |
1054 MessageLoop message_loop_; | 1221 MessageLoop message_loop_; |
1055 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; | 1222 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; |
1056 scoped_refptr<SequencedTaskRunner> task_runner_; | 1223 scoped_refptr<SequencedTaskRunner> task_runner_; |
1057 }; | 1224 }; |
1058 | 1225 |
1059 INSTANTIATE_TYPED_TEST_CASE_P( | 1226 INSTANTIATE_TYPED_TEST_CASE_P( |
1060 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, | 1227 SequencedWorkerPoolSequencedTaskRunner, |
1061 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1228 TaskRunnerTest, |
| 1229 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< |
| 1230 SequencedWorkerPoolRedirection::NONE>); |
1062 INSTANTIATE_TYPED_TEST_CASE_P( | 1231 INSTANTIATE_TYPED_TEST_CASE_P( |
1063 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerAffinityTest, | 1232 SequencedWorkerPoolSequencedTaskRunner, |
1064 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1233 TaskRunnerAffinityTest, |
| 1234 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< |
| 1235 SequencedWorkerPoolRedirection::NONE>); |
| 1236 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1237 SequencedWorkerPoolSequencedTaskRunnerToTaskScheduler, |
| 1238 TaskRunnerAffinityTest, |
| 1239 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< |
| 1240 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); |
1065 | 1241 |
1066 INSTANTIATE_TYPED_TEST_CASE_P( | 1242 INSTANTIATE_TYPED_TEST_CASE_P( |
1067 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, | 1243 SequencedWorkerPoolSequencedTaskRunner, |
1068 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1244 SequencedTaskRunnerTest, |
| 1245 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< |
| 1246 SequencedWorkerPoolRedirection::NONE>); |
1069 INSTANTIATE_TYPED_TEST_CASE_P( | 1247 INSTANTIATE_TYPED_TEST_CASE_P( |
1070 SequencedWorkerPoolSequencedTaskRunner, | 1248 SequencedWorkerPoolSequencedTaskRunner, |
1071 SequencedTaskRunnerDelayedTest, | 1249 SequencedTaskRunnerDelayedTest, |
1072 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1250 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< |
| 1251 SequencedWorkerPoolRedirection::NONE>); |
| 1252 |
| 1253 // Don't run TaskRunnerTest, SequencedTaskRunnerTest and |
| 1254 // SequencedTaskRunnerDelayedTest with sequenced tasks redirected to the |
| 1255 // TaskScheduler. These tests post tasks with and without delays which result in |
| 1256 // getting tasks with different shutdown behaviors in the same sequence. That |
| 1257 // isn't supported by the TaskScheduler. |
1073 | 1258 |
1074 } // namespace | 1259 } // namespace |
1075 | 1260 |
1076 } // namespace base | 1261 } // namespace base |
OLD | NEW |