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 <utility> | 10 #include <utility> |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 class TaskSchedulerTaskTrackerTest | 142 class TaskSchedulerTaskTrackerTest |
143 : public testing::TestWithParam<TaskShutdownBehavior> { | 143 : public testing::TestWithParam<TaskShutdownBehavior> { |
144 protected: | 144 protected: |
145 TaskSchedulerTaskTrackerTest() = default; | 145 TaskSchedulerTaskTrackerTest() = default; |
146 | 146 |
147 // Creates a task with |shutdown_behavior|. | 147 // Creates a task with |shutdown_behavior|. |
148 std::unique_ptr<Task> CreateTask(TaskShutdownBehavior shutdown_behavior) { | 148 std::unique_ptr<Task> CreateTask(TaskShutdownBehavior shutdown_behavior) { |
149 return MakeUnique<Task>( | 149 return MakeUnique<Task>( |
150 FROM_HERE, | 150 FROM_HERE, |
151 Bind(&TaskSchedulerTaskTrackerTest::RunTaskCallback, Unretained(this)), | 151 Bind(&TaskSchedulerTaskTrackerTest::RunTaskCallback, Unretained(this)), |
152 TaskTraits().WithShutdownBehavior(shutdown_behavior), TimeDelta()); | 152 TaskTraits(shutdown_behavior), TimeDelta()); |
153 } | 153 } |
154 | 154 |
155 // Calls tracker_->Shutdown() on a new thread. When this returns, Shutdown() | 155 // Calls tracker_->Shutdown() on a new thread. When this returns, Shutdown() |
156 // method has been entered on the new thread, but it hasn't necessarily | 156 // method has been entered on the new thread, but it hasn't necessarily |
157 // returned. | 157 // returned. |
158 void CallShutdownAsync() { | 158 void CallShutdownAsync() { |
159 ASSERT_FALSE(thread_calling_shutdown_); | 159 ASSERT_FALSE(thread_calling_shutdown_); |
160 thread_calling_shutdown_.reset(new CallbackThread( | 160 thread_calling_shutdown_.reset(new CallbackThread( |
161 Bind(&TaskTracker::Shutdown, Unretained(&tracker_)))); | 161 Bind(&TaskTracker::Shutdown, Unretained(&tracker_)))); |
162 thread_calling_shutdown_->Start(); | 162 thread_calling_shutdown_->Start(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 tracker_.Shutdown(); | 262 tracker_.Shutdown(); |
263 } | 263 } |
264 | 264 |
265 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) { | 265 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) { |
266 // Create a task that signals |task_running| and blocks until |task_barrier| | 266 // Create a task that signals |task_running| and blocks until |task_barrier| |
267 // is signaled. | 267 // is signaled. |
268 WaitableEvent task_running(WaitableEvent::ResetPolicy::AUTOMATIC, | 268 WaitableEvent task_running(WaitableEvent::ResetPolicy::AUTOMATIC, |
269 WaitableEvent::InitialState::NOT_SIGNALED); | 269 WaitableEvent::InitialState::NOT_SIGNALED); |
270 WaitableEvent task_barrier(WaitableEvent::ResetPolicy::AUTOMATIC, | 270 WaitableEvent task_barrier(WaitableEvent::ResetPolicy::AUTOMATIC, |
271 WaitableEvent::InitialState::NOT_SIGNALED); | 271 WaitableEvent::InitialState::NOT_SIGNALED); |
272 auto blocked_task = base::MakeUnique<Task>( | 272 auto blocked_task = MakeUnique<Task>( |
273 FROM_HERE, | 273 FROM_HERE, |
274 Bind( | 274 Bind( |
275 [](WaitableEvent* task_running, WaitableEvent* task_barrier) { | 275 [](WaitableEvent* task_running, WaitableEvent* task_barrier) { |
276 task_running->Signal(); | 276 task_running->Signal(); |
277 task_barrier->Wait(); | 277 task_barrier->Wait(); |
278 }, | 278 }, |
279 Unretained(&task_running), base::Unretained(&task_barrier)), | 279 Unretained(&task_running), Unretained(&task_barrier)), |
280 TaskTraits().WithBaseSyncPrimitives().WithShutdownBehavior(GetParam()), | 280 TaskTraits(WithBaseSyncPrimitives(), GetParam()), TimeDelta()); |
281 TimeDelta()); | |
282 | 281 |
283 // Inform |task_tracker_| that |blocked_task| will be posted. | 282 // Inform |task_tracker_| that |blocked_task| will be posted. |
284 EXPECT_TRUE(tracker_.WillPostTask(blocked_task.get())); | 283 EXPECT_TRUE(tracker_.WillPostTask(blocked_task.get())); |
285 | 284 |
286 // Create a thread to run the task. Wait until the task starts running. | 285 // Create a thread to run the task. Wait until the task starts running. |
287 ThreadPostingAndRunningTask thread_running_task( | 286 ThreadPostingAndRunningTask thread_running_task( |
288 &tracker_, std::move(blocked_task), | 287 &tracker_, std::move(blocked_task), |
289 ThreadPostingAndRunningTask::Action::RUN, false); | 288 ThreadPostingAndRunningTask::Action::RUN, false); |
290 thread_running_task.Start(); | 289 thread_running_task.Start(); |
291 task_running.Wait(); | 290 task_running.Wait(); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 | 421 |
423 // Verify that BLOCK_SHUTDOWN and SKIP_ON_SHUTDOWN tasks can | 422 // Verify that BLOCK_SHUTDOWN and SKIP_ON_SHUTDOWN tasks can |
424 // AssertSingletonAllowed() but CONTINUE_ON_SHUTDOWN tasks can't. | 423 // AssertSingletonAllowed() but CONTINUE_ON_SHUTDOWN tasks can't. |
425 TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) { | 424 TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) { |
426 const bool can_use_singletons = | 425 const bool can_use_singletons = |
427 (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN); | 426 (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN); |
428 | 427 |
429 TaskTracker tracker; | 428 TaskTracker tracker; |
430 std::unique_ptr<Task> task( | 429 std::unique_ptr<Task> task( |
431 new Task(FROM_HERE, BindOnce(&ThreadRestrictions::AssertSingletonAllowed), | 430 new Task(FROM_HERE, BindOnce(&ThreadRestrictions::AssertSingletonAllowed), |
432 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 431 TaskTraits(GetParam()), TimeDelta())); |
433 EXPECT_TRUE(tracker.WillPostTask(task.get())); | 432 EXPECT_TRUE(tracker.WillPostTask(task.get())); |
434 | 433 |
435 // Set the singleton allowed bit to the opposite of what it is expected to be | 434 // Set the singleton allowed bit to the opposite of what it is expected to be |
436 // when |tracker| runs |task| to verify that |tracker| actually sets the | 435 // when |tracker| runs |task| to verify that |tracker| actually sets the |
437 // correct value. | 436 // correct value. |
438 ScopedSetSingletonAllowed scoped_singleton_allowed(!can_use_singletons); | 437 ScopedSetSingletonAllowed scoped_singleton_allowed(!can_use_singletons); |
439 | 438 |
440 // Running the task should fail iff the task isn't allowed to use singletons. | 439 // Running the task should fail iff the task isn't allowed to use singletons. |
441 if (can_use_singletons) { | 440 if (can_use_singletons) { |
442 EXPECT_TRUE(tracker.RunTask(std::move(task), SequenceToken::Create())); | 441 EXPECT_TRUE(tracker.RunTask(std::move(task), SequenceToken::Create())); |
443 } else { | 442 } else { |
444 EXPECT_DCHECK_DEATH( | 443 EXPECT_DCHECK_DEATH( |
445 { tracker.RunTask(std::move(task), SequenceToken::Create()); }); | 444 { tracker.RunTask(std::move(task), SequenceToken::Create()); }); |
446 } | 445 } |
447 } | 446 } |
448 | 447 |
449 // Verify that AssertIOAllowed() succeeds only for a MayBlock() task. | 448 // Verify that AssertIOAllowed() succeeds only for a MayBlock() task. |
450 TEST_P(TaskSchedulerTaskTrackerTest, IOAllowed) { | 449 TEST_P(TaskSchedulerTaskTrackerTest, IOAllowed) { |
451 TaskTracker tracker; | 450 TaskTracker tracker; |
452 | 451 |
453 // Unset the IO allowed bit. Expect TaskTracker to set it before running a | 452 // Unset the IO allowed bit. Expect TaskTracker to set it before running a |
454 // task with the MayBlock() trait. | 453 // task with the MayBlock() trait. |
455 ThreadRestrictions::SetIOAllowed(false); | 454 ThreadRestrictions::SetIOAllowed(false); |
456 auto task_with_may_block = MakeUnique<Task>( | 455 auto task_with_may_block = |
457 FROM_HERE, Bind([]() { | 456 MakeUnique<Task>(FROM_HERE, Bind([]() { |
458 // Shouldn't fail. | 457 // Shouldn't fail. |
459 ThreadRestrictions::AssertIOAllowed(); | 458 ThreadRestrictions::AssertIOAllowed(); |
460 }), | 459 }), |
461 TaskTraits().MayBlock().WithShutdownBehavior(GetParam()), TimeDelta()); | 460 TaskTraits(MayBlock(), GetParam()), TimeDelta()); |
462 EXPECT_TRUE(tracker.WillPostTask(task_with_may_block.get())); | 461 EXPECT_TRUE(tracker.WillPostTask(task_with_may_block.get())); |
463 tracker.RunTask(std::move(task_with_may_block), SequenceToken::Create()); | 462 tracker.RunTask(std::move(task_with_may_block), SequenceToken::Create()); |
464 | 463 |
465 // Set the IO allowed bit. Expect TaskTracker to unset it before running a | 464 // Set the IO allowed bit. Expect TaskTracker to unset it before running a |
466 // task without the MayBlock() trait. | 465 // task without the MayBlock() trait. |
467 ThreadRestrictions::SetIOAllowed(true); | 466 ThreadRestrictions::SetIOAllowed(true); |
468 auto task_without_may_block = MakeUnique<Task>( | 467 auto task_without_may_block = MakeUnique<Task>( |
469 FROM_HERE, Bind([]() { | 468 FROM_HERE, Bind([]() { |
470 EXPECT_DCHECK_DEATH({ ThreadRestrictions::AssertIOAllowed(); }); | 469 EXPECT_DCHECK_DEATH({ ThreadRestrictions::AssertIOAllowed(); }); |
471 }), | 470 }), |
472 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | 471 TaskTraits(GetParam()), TimeDelta()); |
473 EXPECT_TRUE(tracker.WillPostTask(task_without_may_block.get())); | 472 EXPECT_TRUE(tracker.WillPostTask(task_without_may_block.get())); |
474 tracker.RunTask(std::move(task_without_may_block), SequenceToken::Create()); | 473 tracker.RunTask(std::move(task_without_may_block), SequenceToken::Create()); |
475 } | 474 } |
476 | 475 |
477 static void RunTaskRunnerHandleVerificationTask( | 476 static void RunTaskRunnerHandleVerificationTask( |
478 TaskTracker* tracker, | 477 TaskTracker* tracker, |
479 std::unique_ptr<Task> verify_task) { | 478 std::unique_ptr<Task> verify_task) { |
480 // Pretend |verify_task| is posted to respect TaskTracker's contract. | 479 // Pretend |verify_task| is posted to respect TaskTracker's contract. |
481 EXPECT_TRUE(tracker->WillPostTask(verify_task.get())); | 480 EXPECT_TRUE(tracker->WillPostTask(verify_task.get())); |
482 | 481 |
(...skipping 13 matching lines...) Expand all Loading... |
496 static void VerifyNoTaskRunnerHandle() { | 495 static void VerifyNoTaskRunnerHandle() { |
497 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 496 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
498 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 497 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
499 } | 498 } |
500 | 499 |
501 TEST_P(TaskSchedulerTaskTrackerTest, TaskRunnerHandleIsNotSetOnParallel) { | 500 TEST_P(TaskSchedulerTaskTrackerTest, TaskRunnerHandleIsNotSetOnParallel) { |
502 // Create a task that will verify that TaskRunnerHandles are not set in its | 501 // Create a task that will verify that TaskRunnerHandles are not set in its |
503 // scope per no TaskRunner ref being set to it. | 502 // scope per no TaskRunner ref being set to it. |
504 std::unique_ptr<Task> verify_task( | 503 std::unique_ptr<Task> verify_task( |
505 new Task(FROM_HERE, BindOnce(&VerifyNoTaskRunnerHandle), | 504 new Task(FROM_HERE, BindOnce(&VerifyNoTaskRunnerHandle), |
506 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 505 TaskTraits(GetParam()), TimeDelta())); |
507 | 506 |
508 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); | 507 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
509 } | 508 } |
510 | 509 |
511 static void VerifySequencedTaskRunnerHandle( | 510 static void VerifySequencedTaskRunnerHandle( |
512 const SequencedTaskRunner* expected_task_runner) { | 511 const SequencedTaskRunner* expected_task_runner) { |
513 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 512 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
514 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); | 513 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); |
515 EXPECT_EQ(expected_task_runner, SequencedTaskRunnerHandle::Get()); | 514 EXPECT_EQ(expected_task_runner, SequencedTaskRunnerHandle::Get()); |
516 } | 515 } |
517 | 516 |
518 TEST_P(TaskSchedulerTaskTrackerTest, | 517 TEST_P(TaskSchedulerTaskTrackerTest, |
519 SequencedTaskRunnerHandleIsSetOnSequenced) { | 518 SequencedTaskRunnerHandleIsSetOnSequenced) { |
520 scoped_refptr<SequencedTaskRunner> test_task_runner(new TestSimpleTaskRunner); | 519 scoped_refptr<SequencedTaskRunner> test_task_runner(new TestSimpleTaskRunner); |
521 | 520 |
522 // Create a task that will verify that SequencedTaskRunnerHandle is properly | 521 // Create a task that will verify that SequencedTaskRunnerHandle is properly |
523 // set to |test_task_runner| in its scope per |sequenced_task_runner_ref| | 522 // set to |test_task_runner| in its scope per |sequenced_task_runner_ref| |
524 // being set to it. | 523 // being set to it. |
525 std::unique_ptr<Task> verify_task( | 524 std::unique_ptr<Task> verify_task( |
526 new Task(FROM_HERE, | 525 new Task(FROM_HERE, |
527 BindOnce(&VerifySequencedTaskRunnerHandle, | 526 BindOnce(&VerifySequencedTaskRunnerHandle, |
528 base::Unretained(test_task_runner.get())), | 527 Unretained(test_task_runner.get())), |
529 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 528 TaskTraits(GetParam()), TimeDelta())); |
530 verify_task->sequenced_task_runner_ref = test_task_runner; | 529 verify_task->sequenced_task_runner_ref = test_task_runner; |
531 | 530 |
532 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); | 531 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
533 } | 532 } |
534 | 533 |
535 static void VerifyThreadTaskRunnerHandle( | 534 static void VerifyThreadTaskRunnerHandle( |
536 const SingleThreadTaskRunner* expected_task_runner) { | 535 const SingleThreadTaskRunner* expected_task_runner) { |
537 EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); | 536 EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); |
538 // SequencedTaskRunnerHandle inherits ThreadTaskRunnerHandle for thread. | 537 // SequencedTaskRunnerHandle inherits ThreadTaskRunnerHandle for thread. |
539 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); | 538 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); |
540 EXPECT_EQ(expected_task_runner, ThreadTaskRunnerHandle::Get()); | 539 EXPECT_EQ(expected_task_runner, ThreadTaskRunnerHandle::Get()); |
541 } | 540 } |
542 | 541 |
543 TEST_P(TaskSchedulerTaskTrackerTest, | 542 TEST_P(TaskSchedulerTaskTrackerTest, |
544 ThreadTaskRunnerHandleIsSetOnSingleThreaded) { | 543 ThreadTaskRunnerHandleIsSetOnSingleThreaded) { |
545 scoped_refptr<SingleThreadTaskRunner> test_task_runner( | 544 scoped_refptr<SingleThreadTaskRunner> test_task_runner( |
546 new TestSimpleTaskRunner); | 545 new TestSimpleTaskRunner); |
547 | 546 |
548 // Create a task that will verify that ThreadTaskRunnerHandle is properly set | 547 // Create a task that will verify that ThreadTaskRunnerHandle is properly set |
549 // to |test_task_runner| in its scope per |single_thread_task_runner_ref| | 548 // to |test_task_runner| in its scope per |single_thread_task_runner_ref| |
550 // being set on it. | 549 // being set on it. |
551 std::unique_ptr<Task> verify_task( | 550 std::unique_ptr<Task> verify_task( |
552 new Task(FROM_HERE, | 551 new Task(FROM_HERE, |
553 BindOnce(&VerifyThreadTaskRunnerHandle, | 552 BindOnce(&VerifyThreadTaskRunnerHandle, |
554 base::Unretained(test_task_runner.get())), | 553 Unretained(test_task_runner.get())), |
555 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 554 TaskTraits(GetParam()), TimeDelta())); |
556 verify_task->single_thread_task_runner_ref = test_task_runner; | 555 verify_task->single_thread_task_runner_ref = test_task_runner; |
557 | 556 |
558 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); | 557 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
559 } | 558 } |
560 | 559 |
561 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingDelayedTask) { | 560 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingDelayedTask) { |
562 const Task delayed_task(FROM_HERE, BindOnce(&DoNothing), | 561 const Task delayed_task(FROM_HERE, BindOnce(&DoNothing), |
563 TaskTraits().WithShutdownBehavior(GetParam()), | 562 TaskTraits(GetParam()), TimeDelta::FromDays(1)); |
564 TimeDelta::FromDays(1)); | |
565 tracker_.WillPostTask(&delayed_task); | 563 tracker_.WillPostTask(&delayed_task); |
566 // Flush() should return even if the delayed task didn't run. | 564 // Flush() should return even if the delayed task didn't run. |
567 tracker_.Flush(); | 565 tracker_.Flush(); |
568 } | 566 } |
569 | 567 |
570 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingUndelayedTask) { | 568 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingUndelayedTask) { |
571 auto undelayed_task = base::MakeUnique<Task>( | 569 auto undelayed_task = MakeUnique<Task>(FROM_HERE, Bind(&DoNothing), |
572 FROM_HERE, Bind(&DoNothing), | 570 TaskTraits(GetParam()), TimeDelta()); |
573 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | |
574 tracker_.WillPostTask(undelayed_task.get()); | 571 tracker_.WillPostTask(undelayed_task.get()); |
575 | 572 |
576 // Flush() shouldn't return before the undelayed task runs. | 573 // Flush() shouldn't return before the undelayed task runs. |
577 CallFlushAsync(); | 574 CallFlushAsync(); |
578 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 575 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
579 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 576 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
580 | 577 |
581 // Flush() should return after the undelayed task runs. | 578 // Flush() should return after the undelayed task runs. |
582 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); | 579 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); |
583 WAIT_FOR_ASYNC_FLUSH_RETURNED(); | 580 WAIT_FOR_ASYNC_FLUSH_RETURNED(); |
584 } | 581 } |
585 | 582 |
586 TEST_P(TaskSchedulerTaskTrackerTest, PostTaskDuringFlush) { | 583 TEST_P(TaskSchedulerTaskTrackerTest, PostTaskDuringFlush) { |
587 auto undelayed_task = base::MakeUnique<Task>( | 584 auto undelayed_task = MakeUnique<Task>(FROM_HERE, Bind(&DoNothing), |
588 FROM_HERE, Bind(&DoNothing), | 585 TaskTraits(GetParam()), TimeDelta()); |
589 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | |
590 tracker_.WillPostTask(undelayed_task.get()); | 586 tracker_.WillPostTask(undelayed_task.get()); |
591 | 587 |
592 // Flush() shouldn't return before the undelayed task runs. | 588 // Flush() shouldn't return before the undelayed task runs. |
593 CallFlushAsync(); | 589 CallFlushAsync(); |
594 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 590 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
595 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 591 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
596 | 592 |
597 // Simulate posting another undelayed task. | 593 // Simulate posting another undelayed task. |
598 auto other_undelayed_task = base::MakeUnique<Task>( | 594 auto other_undelayed_task = MakeUnique<Task>( |
599 FROM_HERE, Bind(&DoNothing), | 595 FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()), TimeDelta()); |
600 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | |
601 tracker_.WillPostTask(other_undelayed_task.get()); | 596 tracker_.WillPostTask(other_undelayed_task.get()); |
602 | 597 |
603 // Run the first undelayed task. | 598 // Run the first undelayed task. |
604 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); | 599 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); |
605 | 600 |
606 // Flush() shouldn't return before the second undelayed task runs. | 601 // Flush() shouldn't return before the second undelayed task runs. |
607 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 602 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
608 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 603 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
609 | 604 |
610 // Flush() should return after the second undelayed task runs. | 605 // Flush() should return after the second undelayed task runs. |
611 tracker_.RunTask(std::move(other_undelayed_task), SequenceToken::Create()); | 606 tracker_.RunTask(std::move(other_undelayed_task), SequenceToken::Create()); |
612 WAIT_FOR_ASYNC_FLUSH_RETURNED(); | 607 WAIT_FOR_ASYNC_FLUSH_RETURNED(); |
613 } | 608 } |
614 | 609 |
615 TEST_P(TaskSchedulerTaskTrackerTest, RunDelayedTaskDuringFlush) { | 610 TEST_P(TaskSchedulerTaskTrackerTest, RunDelayedTaskDuringFlush) { |
616 // Simulate posting a delayed and an undelayed task. | 611 // Simulate posting a delayed and an undelayed task. |
617 auto delayed_task = base::MakeUnique<Task>( | 612 auto delayed_task = |
618 FROM_HERE, Bind(&DoNothing), | 613 MakeUnique<Task>(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()), |
619 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta::FromDays(1)); | 614 TimeDelta::FromDays(1)); |
620 tracker_.WillPostTask(delayed_task.get()); | 615 tracker_.WillPostTask(delayed_task.get()); |
621 auto undelayed_task = base::MakeUnique<Task>( | 616 auto undelayed_task = MakeUnique<Task>(FROM_HERE, Bind(&DoNothing), |
622 FROM_HERE, Bind(&DoNothing), | 617 TaskTraits(GetParam()), TimeDelta()); |
623 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | |
624 tracker_.WillPostTask(undelayed_task.get()); | 618 tracker_.WillPostTask(undelayed_task.get()); |
625 | 619 |
626 // Flush() shouldn't return before the undelayed task runs. | 620 // Flush() shouldn't return before the undelayed task runs. |
627 CallFlushAsync(); | 621 CallFlushAsync(); |
628 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 622 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
629 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 623 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
630 | 624 |
631 // Run the delayed task. | 625 // Run the delayed task. |
632 tracker_.RunTask(std::move(delayed_task), SequenceToken::Create()); | 626 tracker_.RunTask(std::move(delayed_task), SequenceToken::Create()); |
633 | 627 |
634 // Flush() shouldn't return since there is still a pending undelayed | 628 // Flush() shouldn't return since there is still a pending undelayed |
635 // task. | 629 // task. |
636 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 630 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
637 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 631 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
638 | 632 |
639 // Run the undelayed task. | 633 // Run the undelayed task. |
640 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); | 634 tracker_.RunTask(std::move(undelayed_task), SequenceToken::Create()); |
641 | 635 |
642 // Flush() should now return. | 636 // Flush() should now return. |
643 WAIT_FOR_ASYNC_FLUSH_RETURNED(); | 637 WAIT_FOR_ASYNC_FLUSH_RETURNED(); |
644 } | 638 } |
645 | 639 |
646 TEST_P(TaskSchedulerTaskTrackerTest, FlushAfterShutdown) { | 640 TEST_P(TaskSchedulerTaskTrackerTest, FlushAfterShutdown) { |
647 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) | 641 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) |
648 return; | 642 return; |
649 | 643 |
650 // Simulate posting a task. | 644 // Simulate posting a task. |
651 auto undelayed_task = base::MakeUnique<Task>( | 645 auto undelayed_task = MakeUnique<Task>(FROM_HERE, Bind(&DoNothing), |
652 FROM_HERE, Bind(&DoNothing), | 646 TaskTraits(GetParam()), TimeDelta()); |
653 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | |
654 tracker_.WillPostTask(undelayed_task.get()); | 647 tracker_.WillPostTask(undelayed_task.get()); |
655 | 648 |
656 // Shutdown() should return immediately since there are no pending | 649 // Shutdown() should return immediately since there are no pending |
657 // BLOCK_SHUTDOWN tasks. | 650 // BLOCK_SHUTDOWN tasks. |
658 tracker_.Shutdown(); | 651 tracker_.Shutdown(); |
659 | 652 |
660 // Flush() should return immediately after shutdown, even if an | 653 // Flush() should return immediately after shutdown, even if an |
661 // undelayed task hasn't run. | 654 // undelayed task hasn't run. |
662 tracker_.Flush(); | 655 tracker_.Flush(); |
663 } | 656 } |
664 | 657 |
665 TEST_P(TaskSchedulerTaskTrackerTest, ShutdownDuringFlush) { | 658 TEST_P(TaskSchedulerTaskTrackerTest, ShutdownDuringFlush) { |
666 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) | 659 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) |
667 return; | 660 return; |
668 | 661 |
669 // Simulate posting a task. | 662 // Simulate posting a task. |
670 auto undelayed_task = base::MakeUnique<Task>( | 663 auto undelayed_task = MakeUnique<Task>(FROM_HERE, Bind(&DoNothing), |
671 FROM_HERE, Bind(&DoNothing), | 664 TaskTraits(GetParam()), TimeDelta()); |
672 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | |
673 tracker_.WillPostTask(undelayed_task.get()); | 665 tracker_.WillPostTask(undelayed_task.get()); |
674 | 666 |
675 // Flush() shouldn't return before the undelayed task runs or | 667 // Flush() shouldn't return before the undelayed task runs or |
676 // shutdown completes. | 668 // shutdown completes. |
677 CallFlushAsync(); | 669 CallFlushAsync(); |
678 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 670 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
679 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); | 671 VERIFY_ASYNC_FLUSH_IN_PROGRESS(); |
680 | 672 |
681 // Shutdown() should return immediately since there are no pending | 673 // Shutdown() should return immediately since there are no pending |
682 // BLOCK_SHUTDOWN tasks. | 674 // BLOCK_SHUTDOWN tasks. |
(...skipping 21 matching lines...) Expand all Loading... |
704 void ExpectSequenceToken(SequenceToken sequence_token) { | 696 void ExpectSequenceToken(SequenceToken sequence_token) { |
705 EXPECT_EQ(sequence_token, SequenceToken::GetForCurrentThread()); | 697 EXPECT_EQ(sequence_token, SequenceToken::GetForCurrentThread()); |
706 } | 698 } |
707 | 699 |
708 } // namespace | 700 } // namespace |
709 | 701 |
710 // Verify that SequenceToken::GetForCurrentThread() returns the Sequence's token | 702 // Verify that SequenceToken::GetForCurrentThread() returns the Sequence's token |
711 // when a Task runs. | 703 // when a Task runs. |
712 TEST_F(TaskSchedulerTaskTrackerTest, CurrentSequenceToken) { | 704 TEST_F(TaskSchedulerTaskTrackerTest, CurrentSequenceToken) { |
713 const SequenceToken sequence_token(SequenceToken::Create()); | 705 const SequenceToken sequence_token(SequenceToken::Create()); |
714 auto task = base::MakeUnique<Task>(FROM_HERE, | 706 auto task = |
715 Bind(&ExpectSequenceToken, sequence_token), | 707 MakeUnique<Task>(FROM_HERE, Bind(&ExpectSequenceToken, sequence_token), |
716 TaskTraits(), TimeDelta()); | 708 TaskTraits(), TimeDelta()); |
717 tracker_.WillPostTask(task.get()); | 709 tracker_.WillPostTask(task.get()); |
718 | 710 |
719 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); | 711 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
720 EXPECT_TRUE(tracker_.RunTask(std::move(task), sequence_token)); | 712 EXPECT_TRUE(tracker_.RunTask(std::move(task), sequence_token)); |
721 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); | 713 EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid()); |
722 } | 714 } |
723 | 715 |
724 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { | 716 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
725 // Post and run tasks asynchronously. | 717 // Post and run tasks asynchronously. |
726 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 718 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 SequenceToken::Create()); | 864 SequenceToken::Create()); |
873 | 865 |
874 // Disallow waiting. Expect TaskTracker to allow it before running a task | 866 // Disallow waiting. Expect TaskTracker to allow it before running a task |
875 // with the WithBaseSyncPrimitives() trait. | 867 // with the WithBaseSyncPrimitives() trait. |
876 ThreadRestrictions::DisallowWaiting(); | 868 ThreadRestrictions::DisallowWaiting(); |
877 auto task_with_sync_primitives = | 869 auto task_with_sync_primitives = |
878 MakeUnique<Task>(FROM_HERE, Bind([]() { | 870 MakeUnique<Task>(FROM_HERE, Bind([]() { |
879 // Shouldn't fail. | 871 // Shouldn't fail. |
880 ThreadRestrictions::AssertWaitAllowed(); | 872 ThreadRestrictions::AssertWaitAllowed(); |
881 }), | 873 }), |
882 TaskTraits().WithBaseSyncPrimitives(), TimeDelta()); | 874 TaskTraits(WithBaseSyncPrimitives()), TimeDelta()); |
883 EXPECT_TRUE(tracker.WillPostTask(task_with_sync_primitives.get())); | 875 EXPECT_TRUE(tracker.WillPostTask(task_with_sync_primitives.get())); |
884 tracker.RunTask(std::move(task_with_sync_primitives), | 876 tracker.RunTask(std::move(task_with_sync_primitives), |
885 SequenceToken::Create()); | 877 SequenceToken::Create()); |
886 } | 878 } |
887 | 879 |
888 DISALLOW_COPY_AND_ASSIGN(WaitAllowedTestThread); | 880 DISALLOW_COPY_AND_ASSIGN(WaitAllowedTestThread); |
889 }; | 881 }; |
890 | 882 |
891 } // namespace | 883 } // namespace |
892 | 884 |
(...skipping 12 matching lines...) Expand all Loading... |
905 // when a task runs. | 897 // when a task runs. |
906 TEST(TaskSchedulerTaskTrackerHistogramTest, TaskLatency) { | 898 TEST(TaskSchedulerTaskTrackerHistogramTest, TaskLatency) { |
907 auto statistics_recorder = StatisticsRecorder::CreateTemporaryForTesting(); | 899 auto statistics_recorder = StatisticsRecorder::CreateTemporaryForTesting(); |
908 | 900 |
909 TaskTracker tracker; | 901 TaskTracker tracker; |
910 | 902 |
911 struct { | 903 struct { |
912 const TaskTraits traits; | 904 const TaskTraits traits; |
913 const char* const expected_histogram; | 905 const char* const expected_histogram; |
914 } tests[] = { | 906 } tests[] = { |
915 {TaskTraits().WithPriority(TaskPriority::BACKGROUND), | 907 {{TaskPriority::BACKGROUND}, |
916 "TaskScheduler.TaskLatencyMicroseconds.BackgroundTaskPriority"}, | 908 "TaskScheduler.TaskLatencyMicroseconds.BackgroundTaskPriority"}, |
917 {TaskTraits().WithPriority(TaskPriority::BACKGROUND).MayBlock(), | 909 {{MayBlock(), TaskPriority::BACKGROUND}, |
918 "TaskScheduler.TaskLatencyMicroseconds.BackgroundTaskPriority.MayBlock"}, | 910 "TaskScheduler.TaskLatencyMicroseconds.BackgroundTaskPriority.MayBlock"}, |
919 {TaskTraits() | 911 {{WithBaseSyncPrimitives(), TaskPriority::BACKGROUND}, |
920 .WithPriority(TaskPriority::BACKGROUND) | |
921 .WithBaseSyncPrimitives(), | |
922 "TaskScheduler.TaskLatencyMicroseconds.BackgroundTaskPriority.MayBlock"}, | 912 "TaskScheduler.TaskLatencyMicroseconds.BackgroundTaskPriority.MayBlock"}, |
923 {TaskTraits().WithPriority(TaskPriority::USER_VISIBLE), | 913 {{TaskPriority::USER_VISIBLE}, |
924 "TaskScheduler.TaskLatencyMicroseconds.UserVisibleTaskPriority"}, | 914 "TaskScheduler.TaskLatencyMicroseconds.UserVisibleTaskPriority"}, |
925 {TaskTraits().WithPriority(TaskPriority::USER_VISIBLE).MayBlock(), | 915 {{MayBlock(), TaskPriority::USER_VISIBLE}, |
926 "TaskScheduler.TaskLatencyMicroseconds.UserVisibleTaskPriority." | 916 "TaskScheduler.TaskLatencyMicroseconds.UserVisibleTaskPriority." |
927 "MayBlock"}, | 917 "MayBlock"}, |
928 {TaskTraits() | 918 {{WithBaseSyncPrimitives(), TaskPriority::USER_VISIBLE}, |
929 .WithPriority(TaskPriority::USER_VISIBLE) | |
930 .WithBaseSyncPrimitives(), | |
931 "TaskScheduler.TaskLatencyMicroseconds.UserVisibleTaskPriority." | 919 "TaskScheduler.TaskLatencyMicroseconds.UserVisibleTaskPriority." |
932 "MayBlock"}, | 920 "MayBlock"}, |
933 {TaskTraits().WithPriority(TaskPriority::USER_BLOCKING), | 921 {{TaskPriority::USER_BLOCKING}, |
934 "TaskScheduler.TaskLatencyMicroseconds.UserBlockingTaskPriority"}, | 922 "TaskScheduler.TaskLatencyMicroseconds.UserBlockingTaskPriority"}, |
935 {TaskTraits().WithPriority(TaskPriority::USER_BLOCKING).MayBlock(), | 923 {{MayBlock(), TaskPriority::USER_BLOCKING}, |
936 "TaskScheduler.TaskLatencyMicroseconds.UserBlockingTaskPriority." | 924 "TaskScheduler.TaskLatencyMicroseconds.UserBlockingTaskPriority." |
937 "MayBlock"}, | 925 "MayBlock"}, |
938 {TaskTraits() | 926 {{WithBaseSyncPrimitives(), TaskPriority::USER_BLOCKING}, |
939 .WithPriority(TaskPriority::USER_BLOCKING) | |
940 .WithBaseSyncPrimitives(), | |
941 "TaskScheduler.TaskLatencyMicroseconds.UserBlockingTaskPriority." | 927 "TaskScheduler.TaskLatencyMicroseconds.UserBlockingTaskPriority." |
942 "MayBlock"}}; | 928 "MayBlock"}}; |
943 | 929 |
944 for (const auto& test : tests) { | 930 for (const auto& test : tests) { |
945 auto task = | 931 auto task = |
946 MakeUnique<Task>(FROM_HERE, Bind(&DoNothing), test.traits, TimeDelta()); | 932 MakeUnique<Task>(FROM_HERE, Bind(&DoNothing), test.traits, TimeDelta()); |
947 ASSERT_TRUE(tracker.WillPostTask(task.get())); | 933 ASSERT_TRUE(tracker.WillPostTask(task.get())); |
948 | 934 |
949 HistogramTester tester; | 935 HistogramTester tester; |
950 EXPECT_TRUE(tracker.RunTask(std::move(task), SequenceToken::Create())); | 936 EXPECT_TRUE(tracker.RunTask(std::move(task), SequenceToken::Create())); |
951 tester.ExpectTotalCount(test.expected_histogram, 1); | 937 tester.ExpectTotalCount(test.expected_histogram, 1); |
952 } | 938 } |
953 } | 939 } |
954 | 940 |
955 } // namespace internal | 941 } // namespace internal |
956 } // namespace base | 942 } // namespace base |
OLD | NEW |