| 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 const bool previous_value_; | 120 const bool previous_value_; |
| 121 }; | 121 }; |
| 122 | 122 |
| 123 class TaskSchedulerTaskTrackerTest | 123 class TaskSchedulerTaskTrackerTest |
| 124 : public testing::TestWithParam<TaskShutdownBehavior> { | 124 : public testing::TestWithParam<TaskShutdownBehavior> { |
| 125 protected: | 125 protected: |
| 126 TaskSchedulerTaskTrackerTest() = default; | 126 TaskSchedulerTaskTrackerTest() = default; |
| 127 | 127 |
| 128 // Creates a task with |shutdown_behavior|. | 128 // Creates a task with |shutdown_behavior|. |
| 129 std::unique_ptr<Task> CreateTask(TaskShutdownBehavior shutdown_behavior) { | 129 std::unique_ptr<Task> CreateTask(TaskShutdownBehavior shutdown_behavior) { |
| 130 return WrapUnique(new Task( | 130 return MakeUnique<Task>( |
| 131 FROM_HERE, | 131 FROM_HERE, |
| 132 Bind(&TaskSchedulerTaskTrackerTest::RunTaskCallback, Unretained(this)), | 132 Bind(&TaskSchedulerTaskTrackerTest::RunTaskCallback, Unretained(this)), |
| 133 TaskTraits().WithShutdownBehavior(shutdown_behavior), TimeDelta())); | 133 TaskTraits().WithShutdownBehavior(shutdown_behavior), TimeDelta()); |
| 134 } | 134 } |
| 135 | 135 |
| 136 // Calls tracker_->Shutdown() on a new thread. When this returns, Shutdown() | 136 // Calls tracker_->Shutdown() on a new thread. When this returns, Shutdown() |
| 137 // method has been entered on the new thread, but it hasn't necessarily | 137 // method has been entered on the new thread, but it hasn't necessarily |
| 138 // returned. | 138 // returned. |
| 139 void CallShutdownAsync() { | 139 void CallShutdownAsync() { |
| 140 ASSERT_FALSE(thread_calling_shutdown_); | 140 ASSERT_FALSE(thread_calling_shutdown_); |
| 141 thread_calling_shutdown_.reset(new ThreadCallingShutdown(&tracker_)); | 141 thread_calling_shutdown_.reset(new ThreadCallingShutdown(&tracker_)); |
| 142 thread_calling_shutdown_->Start(); | 142 thread_calling_shutdown_->Start(); |
| 143 while (!tracker_.HasShutdownStarted()) | 143 while (!tracker_.HasShutdownStarted()) |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); | 505 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
| 506 tracker_.RunNextTaskInSequence(sequence.get()); | 506 tracker_.RunNextTaskInSequence(sequence.get()); |
| 507 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); | 507 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
| 508 } | 508 } |
| 509 | 509 |
| 510 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { | 510 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
| 511 // Post and run tasks asynchronously. | 511 // Post and run tasks asynchronously. |
| 512 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 512 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
| 513 | 513 |
| 514 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 514 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| 515 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 515 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 516 &tracker_, CreateSequenceWithTask( | 516 &tracker_, CreateSequenceWithTask( |
| 517 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), | 517 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), |
| 518 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 518 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 519 threads.back()->Start(); | 519 threads.back()->Start(); |
| 520 | 520 |
| 521 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 521 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 522 &tracker_, CreateSequenceWithTask( | 522 &tracker_, CreateSequenceWithTask( |
| 523 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), | 523 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), |
| 524 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 524 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 525 threads.back()->Start(); | 525 threads.back()->Start(); |
| 526 | 526 |
| 527 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 527 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 528 &tracker_, CreateSequenceWithTask( | 528 &tracker_, CreateSequenceWithTask( |
| 529 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), | 529 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), |
| 530 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 530 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 531 threads.back()->Start(); | 531 threads.back()->Start(); |
| 532 } | 532 } |
| 533 | 533 |
| 534 for (const auto& thread : threads) | 534 for (const auto& thread : threads) |
| 535 thread->Join(); | 535 thread->Join(); |
| 536 | 536 |
| 537 // Expect all tasks to be executed. | 537 // Expect all tasks to be executed. |
| 538 EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted()); | 538 EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted()); |
| 539 | 539 |
| 540 // Should return immediately because no tasks are blocking shutdown. | 540 // Should return immediately because no tasks are blocking shutdown. |
| 541 tracker_.Shutdown(); | 541 tracker_.Shutdown(); |
| 542 } | 542 } |
| 543 | 543 |
| 544 TEST_F(TaskSchedulerTaskTrackerTest, | 544 TEST_F(TaskSchedulerTaskTrackerTest, |
| 545 LoadWillPostBeforeShutdownAndRunDuringShutdown) { | 545 LoadWillPostBeforeShutdownAndRunDuringShutdown) { |
| 546 // Post tasks asynchronously. | 546 // Post tasks asynchronously. |
| 547 std::vector<scoped_refptr<Sequence>> sequences; | 547 std::vector<scoped_refptr<Sequence>> sequences; |
| 548 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads; | 548 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads; |
| 549 | 549 |
| 550 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 550 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| 551 sequences.push_back(CreateSequenceWithTask( | 551 sequences.push_back(CreateSequenceWithTask( |
| 552 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN))); | 552 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN))); |
| 553 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 553 post_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 554 &tracker_, sequences.back(), | 554 &tracker_, sequences.back(), |
| 555 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 555 ThreadPostingAndRunningTask::Action::WILL_POST, true)); |
| 556 post_threads.back()->Start(); | 556 post_threads.back()->Start(); |
| 557 | 557 |
| 558 sequences.push_back(CreateSequenceWithTask( | 558 sequences.push_back(CreateSequenceWithTask( |
| 559 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN))); | 559 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN))); |
| 560 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 560 post_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 561 &tracker_, sequences.back(), | 561 &tracker_, sequences.back(), |
| 562 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 562 ThreadPostingAndRunningTask::Action::WILL_POST, true)); |
| 563 post_threads.back()->Start(); | 563 post_threads.back()->Start(); |
| 564 | 564 |
| 565 sequences.push_back(CreateSequenceWithTask( | 565 sequences.push_back(CreateSequenceWithTask( |
| 566 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN))); | 566 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN))); |
| 567 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 567 post_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 568 &tracker_, sequences.back(), | 568 &tracker_, sequences.back(), |
| 569 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 569 ThreadPostingAndRunningTask::Action::WILL_POST, true)); |
| 570 post_threads.back()->Start(); | 570 post_threads.back()->Start(); |
| 571 } | 571 } |
| 572 | 572 |
| 573 for (const auto& thread : post_threads) | 573 for (const auto& thread : post_threads) |
| 574 thread->Join(); | 574 thread->Join(); |
| 575 | 575 |
| 576 // Call Shutdown() asynchronously. | 576 // Call Shutdown() asynchronously. |
| 577 CallShutdownAsync(); | 577 CallShutdownAsync(); |
| 578 | 578 |
| 579 // Run tasks asynchronously. | 579 // Run tasks asynchronously. |
| 580 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; | 580 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; |
| 581 | 581 |
| 582 for (const auto& sequence : sequences) { | 582 for (const auto& sequence : sequences) { |
| 583 run_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 583 run_threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 584 &tracker_, sequence, ThreadPostingAndRunningTask::Action::RUN, false))); | 584 &tracker_, sequence, ThreadPostingAndRunningTask::Action::RUN, false)); |
| 585 run_threads.back()->Start(); | 585 run_threads.back()->Start(); |
| 586 } | 586 } |
| 587 | 587 |
| 588 for (const auto& thread : run_threads) | 588 for (const auto& thread : run_threads) |
| 589 thread->Join(); | 589 thread->Join(); |
| 590 | 590 |
| 591 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 591 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 592 | 592 |
| 593 // Expect BLOCK_SHUTDOWN tasks to have been executed. | 593 // Expect BLOCK_SHUTDOWN tasks to have been executed. |
| 594 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); | 594 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); |
| 595 } | 595 } |
| 596 | 596 |
| 597 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { | 597 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { |
| 598 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to | 598 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to |
| 599 // block shutdown. | 599 // block shutdown. |
| 600 std::unique_ptr<Task> block_shutdown_task( | 600 std::unique_ptr<Task> block_shutdown_task( |
| 601 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 601 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
| 602 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); | 602 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); |
| 603 | 603 |
| 604 // Call Shutdown() asynchronously. | 604 // Call Shutdown() asynchronously. |
| 605 CallShutdownAsync(); | 605 CallShutdownAsync(); |
| 606 | 606 |
| 607 // Post and run tasks asynchronously. | 607 // Post and run tasks asynchronously. |
| 608 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 608 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
| 609 | 609 |
| 610 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 610 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
| 611 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 611 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 612 &tracker_, CreateSequenceWithTask( | 612 &tracker_, CreateSequenceWithTask( |
| 613 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), | 613 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), |
| 614 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); | 614 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false)); |
| 615 threads.back()->Start(); | 615 threads.back()->Start(); |
| 616 | 616 |
| 617 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 617 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 618 &tracker_, CreateSequenceWithTask( | 618 &tracker_, CreateSequenceWithTask( |
| 619 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), | 619 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), |
| 620 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); | 620 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false)); |
| 621 threads.back()->Start(); | 621 threads.back()->Start(); |
| 622 | 622 |
| 623 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 623 threads.push_back(MakeUnique<ThreadPostingAndRunningTask>( |
| 624 &tracker_, CreateSequenceWithTask( | 624 &tracker_, CreateSequenceWithTask( |
| 625 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), | 625 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), |
| 626 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 626 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true)); |
| 627 threads.back()->Start(); | 627 threads.back()->Start(); |
| 628 } | 628 } |
| 629 | 629 |
| 630 for (const auto& thread : threads) | 630 for (const auto& thread : threads) |
| 631 thread->Join(); | 631 thread->Join(); |
| 632 | 632 |
| 633 // Expect BLOCK_SHUTDOWN tasks to have been executed. | 633 // Expect BLOCK_SHUTDOWN tasks to have been executed. |
| 634 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); | 634 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); |
| 635 | 635 |
| 636 // Shutdown() shouldn't return before |block_shutdown_task| is executed. | 636 // Shutdown() shouldn't return before |block_shutdown_task| is executed. |
| 637 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 637 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
| 638 | 638 |
| 639 // Unblock shutdown by running |block_shutdown_task|. | 639 // Unblock shutdown by running |block_shutdown_task|. |
| 640 tracker_.RunNextTaskInSequence( | 640 tracker_.RunNextTaskInSequence( |
| 641 CreateSequenceWithTask(std::move(block_shutdown_task)).get()); | 641 CreateSequenceWithTask(std::move(block_shutdown_task)).get()); |
| 642 EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); | 642 EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); |
| 643 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 643 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
| 644 } | 644 } |
| 645 | 645 |
| 646 } // namespace internal | 646 } // namespace internal |
| 647 } // namespace base | 647 } // namespace base |
| OLD | NEW |