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 |