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 |