| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_scheduler/task_tracker.h" | 5 #include "base/task_scheduler/task_tracker.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 const bool previous_value_; | 113 const bool previous_value_; |
| 114 }; | 114 }; |
| 115 | 115 |
| 116 class TaskSchedulerTaskTrackerTest | 116 class TaskSchedulerTaskTrackerTest |
| 117 : public testing::TestWithParam<TaskShutdownBehavior> { | 117 : public testing::TestWithParam<TaskShutdownBehavior> { |
| 118 protected: | 118 protected: |
| 119 TaskSchedulerTaskTrackerTest() = default; | 119 TaskSchedulerTaskTrackerTest() = default; |
| 120 | 120 |
| 121 // Creates a task with |shutdown_behavior|. | 121 // Creates a task with |shutdown_behavior|. |
| 122 std::unique_ptr<Task> CreateTask(TaskShutdownBehavior shutdown_behavior) { | 122 std::unique_ptr<Task> CreateTask(TaskShutdownBehavior shutdown_behavior) { |
| 123 return WrapUnique(new Task( | 123 return MakeUnique<Task>( |
| 124 FROM_HERE, | 124 FROM_HERE, |
| 125 Bind(&TaskSchedulerTaskTrackerTest::RunTaskCallback, Unretained(this)), | 125 Bind(&TaskSchedulerTaskTrackerTest::RunTaskCallback, Unretained(this)), |
| 126 TaskTraits().WithShutdownBehavior(shutdown_behavior), TimeDelta())); | 126 TaskTraits().WithShutdownBehavior(shutdown_behavior), TimeDelta()); |
| 127 } | 127 } |
| 128 | 128 |
| 129 // Calls tracker_->Shutdown() on a new thread. When this returns, Shutdown() | 129 // Calls tracker_->Shutdown() on a new thread. When this returns, Shutdown() |
| 130 // method has been entered on the new thread, but it hasn't necessarily | 130 // method has been entered on the new thread, but it hasn't necessarily |
| 131 // returned. | 131 // returned. |
| 132 void CallShutdownAsync() { | 132 void CallShutdownAsync() { |
| 133 ASSERT_FALSE(thread_calling_shutdown_); | 133 ASSERT_FALSE(thread_calling_shutdown_); |
| 134 thread_calling_shutdown_.reset(new ThreadCallingShutdown(&tracker_)); | 134 thread_calling_shutdown_.reset(new ThreadCallingShutdown(&tracker_)); |
| 135 thread_calling_shutdown_->Start(); | 135 thread_calling_shutdown_->Start(); |
| 136 while (!tracker_.HasShutdownStarted()) | 136 while (!tracker_.HasShutdownStarted()) |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); | 489 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
| 490 } | 490 } |
| 491 | 491 |
| 492 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { | 492 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
| 493 // Post and run tasks asynchronously. | 493 // Post and run tasks asynchronously. |
| 494 std::vector<std::unique_ptr<Task>> tasks; | 494 std::vector<std::unique_ptr<Task>> tasks; |
| 495 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 495 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
| 496 | 496 |
| 497 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 497 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| 498 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 498 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
| 499 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 499 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 500 &tracker_, tasks.back().get(), | 500 &tracker_, tasks.back().get(), |
| 501 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 501 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 502 threads.back()->Start(); | 502 threads.back()->Start(); |
| 503 | 503 |
| 504 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 504 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
| 505 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 505 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 506 &tracker_, tasks.back().get(), | 506 &tracker_, tasks.back().get(), |
| 507 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 507 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 508 threads.back()->Start(); | 508 threads.back()->Start(); |
| 509 | 509 |
| 510 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 510 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 511 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 511 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 512 &tracker_, tasks.back().get(), | 512 &tracker_, tasks.back().get(), |
| 513 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 513 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 514 threads.back()->Start(); | 514 threads.back()->Start(); |
| 515 } | 515 } |
| 516 | 516 |
| 517 for (const auto& thread : threads) | 517 for (const auto& thread : threads) |
| 518 thread->Join(); | 518 thread->Join(); |
| 519 | 519 |
| 520 // Expect all tasks to be executed. | 520 // Expect all tasks to be executed. |
| 521 EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted()); | 521 EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted()); |
| 522 | 522 |
| 523 // Should return immediately because no tasks are blocking shutdown. | 523 // Should return immediately because no tasks are blocking shutdown. |
| 524 tracker_.Shutdown(); | 524 tracker_.Shutdown(); |
| 525 } | 525 } |
| 526 | 526 |
| 527 TEST_F(TaskSchedulerTaskTrackerTest, | 527 TEST_F(TaskSchedulerTaskTrackerTest, |
| 528 LoadWillPostBeforeShutdownAndRunDuringShutdown) { | 528 LoadWillPostBeforeShutdownAndRunDuringShutdown) { |
| 529 // Post tasks asynchronously. | 529 // Post tasks asynchronously. |
| 530 std::vector<std::unique_ptr<Task>> tasks; | 530 std::vector<std::unique_ptr<Task>> tasks; |
| 531 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads; | 531 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads; |
| 532 | 532 |
| 533 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 533 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| 534 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 534 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
| 535 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 535 post_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 536 &tracker_, tasks.back().get(), | 536 &tracker_, tasks.back().get(), |
| 537 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 537 ThreadPostingAndRunningTask::Action::WILL_POST, true)); |
| 538 post_threads.back()->Start(); | 538 post_threads.back()->Start(); |
| 539 | 539 |
| 540 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 540 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
| 541 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 541 post_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 542 &tracker_, tasks.back().get(), | 542 &tracker_, tasks.back().get(), |
| 543 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 543 ThreadPostingAndRunningTask::Action::WILL_POST, true)); |
| 544 post_threads.back()->Start(); | 544 post_threads.back()->Start(); |
| 545 | 545 |
| 546 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 546 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 547 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 547 post_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 548 &tracker_, tasks.back().get(), | 548 &tracker_, tasks.back().get(), |
| 549 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 549 ThreadPostingAndRunningTask::Action::WILL_POST, true)); |
| 550 post_threads.back()->Start(); | 550 post_threads.back()->Start(); |
| 551 } | 551 } |
| 552 | 552 |
| 553 for (const auto& thread : post_threads) | 553 for (const auto& thread : post_threads) |
| 554 thread->Join(); | 554 thread->Join(); |
| 555 | 555 |
| 556 // Call Shutdown() asynchronously. | 556 // Call Shutdown() asynchronously. |
| 557 CallShutdownAsync(); | 557 CallShutdownAsync(); |
| 558 | 558 |
| 559 // Run tasks asynchronously. | 559 // Run tasks asynchronously. |
| 560 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; | 560 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; |
| 561 | 561 |
| 562 for (const auto& task : tasks) { | 562 for (const auto& task : tasks) { |
| 563 run_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 563 run_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 564 &tracker_, task.get(), ThreadPostingAndRunningTask::Action::RUN, | 564 &tracker_, task.get(), ThreadPostingAndRunningTask::Action::RUN, |
| 565 false))); | 565 false)); |
| 566 run_threads.back()->Start(); | 566 run_threads.back()->Start(); |
| 567 } | 567 } |
| 568 | 568 |
| 569 for (const auto& thread : run_threads) | 569 for (const auto& thread : run_threads) |
| 570 thread->Join(); | 570 thread->Join(); |
| 571 | 571 |
| 572 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 572 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 573 | 573 |
| 574 // Expect BLOCK_SHUTDOWN tasks to have been executed. | 574 // Expect BLOCK_SHUTDOWN tasks to have been executed. |
| 575 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); | 575 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); |
| 576 } | 576 } |
| 577 | 577 |
| 578 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { | 578 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { |
| 579 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to | 579 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to |
| 580 // block shutdown. | 580 // block shutdown. |
| 581 std::unique_ptr<Task> block_shutdown_task( | 581 std::unique_ptr<Task> block_shutdown_task( |
| 582 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 582 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 583 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); | 583 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); |
| 584 | 584 |
| 585 // Call Shutdown() asynchronously. | 585 // Call Shutdown() asynchronously. |
| 586 CallShutdownAsync(); | 586 CallShutdownAsync(); |
| 587 | 587 |
| 588 // Post and run tasks asynchronously. | 588 // Post and run tasks asynchronously. |
| 589 std::vector<std::unique_ptr<Task>> tasks; | 589 std::vector<std::unique_ptr<Task>> tasks; |
| 590 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 590 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
| 591 | 591 |
| 592 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 592 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| 593 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 593 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
| 594 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 594 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 595 &tracker_, tasks.back().get(), | 595 &tracker_, tasks.back().get(), |
| 596 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); | 596 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false)); |
| 597 threads.back()->Start(); | 597 threads.back()->Start(); |
| 598 | 598 |
| 599 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 599 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
| 600 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 600 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 601 &tracker_, tasks.back().get(), | 601 &tracker_, tasks.back().get(), |
| 602 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); | 602 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false)); |
| 603 threads.back()->Start(); | 603 threads.back()->Start(); |
| 604 | 604 |
| 605 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 605 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 606 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 606 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 607 &tracker_, tasks.back().get(), | 607 &tracker_, tasks.back().get(), |
| 608 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 608 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 609 threads.back()->Start(); | 609 threads.back()->Start(); |
| 610 } | 610 } |
| 611 | 611 |
| 612 for (const auto& thread : threads) | 612 for (const auto& thread : threads) |
| 613 thread->Join(); | 613 thread->Join(); |
| 614 | 614 |
| 615 // Expect BLOCK_SHUTDOWN tasks to have been executed. | 615 // Expect BLOCK_SHUTDOWN tasks to have been executed. |
| 616 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); | 616 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); |
| 617 | 617 |
| 618 // Shutdown() shouldn't return before |block_shutdown_task| is executed. | 618 // Shutdown() shouldn't return before |block_shutdown_task| is executed. |
| 619 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 619 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| 620 | 620 |
| 621 // Unblock shutdown by running |block_shutdown_task|. | 621 // Unblock shutdown by running |block_shutdown_task|. |
| 622 EXPECT_TRUE( | 622 EXPECT_TRUE( |
| 623 tracker_.RunTask(block_shutdown_task.get(), SequenceToken::Create())); | 623 tracker_.RunTask(block_shutdown_task.get(), SequenceToken::Create())); |
| 624 EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); | 624 EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); |
| 625 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 625 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 626 } | 626 } |
| 627 | 627 |
| 628 } // namespace internal | 628 } // namespace internal |
| 629 } // namespace base | 629 } // namespace base |
| OLD | NEW |