Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: base/timer/timer_unittest.cc

Issue 1532773002: Revert of Use SequenceChecker to allow Timer to run in SequencedWorkerPool (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/timer/timer.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/bind_helpers.h"
6 #include "base/callback.h"
7 #include "base/memory/scoped_ptr.h" 5 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h" 6 #include "base/message_loop/message_loop.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/test/sequenced_worker_pool_owner.h"
11 #include "base/test/test_simple_task_runner.h" 7 #include "base/test/test_simple_task_runner.h"
12 #include "base/timer/timer.h" 8 #include "base/timer/timer.h"
13 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
14 10
15 using base::DoNothing;
16 using base::SequencedTaskRunner;
17 using base::TimeDelta; 11 using base::TimeDelta;
12 using base::SingleThreadTaskRunner;
18 13
19 namespace { 14 namespace {
20 15
21 // The message loops on which each timer should be tested. 16 // The message loops on which each timer should be tested.
22 const base::MessageLoop::Type testing_message_loops[] = { 17 const base::MessageLoop::Type testing_message_loops[] = {
23 base::MessageLoop::TYPE_DEFAULT, 18 base::MessageLoop::TYPE_DEFAULT,
24 base::MessageLoop::TYPE_IO, 19 base::MessageLoop::TYPE_IO,
25 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop. 20 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
26 base::MessageLoop::TYPE_UI, 21 base::MessageLoop::TYPE_UI,
27 #endif 22 #endif
28 }; 23 };
29 24
30 const int kNumTestingMessageLoops = arraysize(testing_message_loops); 25 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
31 26
32 class OneShotTimerTester { 27 class OneShotTimerTester {
33 public: 28 public:
34 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10) 29 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10)
35 : did_run_(did_run), 30 : did_run_(did_run),
36 delay_ms_(milliseconds), 31 delay_ms_(milliseconds),
37 quit_message_loop_(true) { 32 quit_message_loop_(true) {
38 } 33 }
39 34
40 void Start() { 35 void Start() {
41 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this, 36 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this,
42 &OneShotTimerTester::Run); 37 &OneShotTimerTester::Run);
43 } 38 }
44 39
45 void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) { 40 void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) {
46 quit_message_loop_ = false; 41 quit_message_loop_ = false;
47 timer_.SetTaskRunner(task_runner); 42 timer_.SetTaskRunner(task_runner);
48 } 43 }
49 44
50 private: 45 private:
51 void Run() { 46 void Run() {
52 *did_run_ = true; 47 *did_run_ = true;
53 if (quit_message_loop_) { 48 if (quit_message_loop_) {
54 base::MessageLoop::current()->QuitWhenIdle(); 49 base::MessageLoop::current()->QuitWhenIdle();
55 } 50 }
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10), 521 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
527 base::Bind(&SetCallbackHappened1)); 522 base::Bind(&SetCallbackHappened1));
528 timer.Reset(); 523 timer.Reset();
529 // Since Reset happened before task ran, the user_task must not be cleared: 524 // Since Reset happened before task ran, the user_task must not be cleared:
530 ASSERT_FALSE(timer.user_task().is_null()); 525 ASSERT_FALSE(timer.user_task().is_null());
531 base::MessageLoop::current()->Run(); 526 base::MessageLoop::current()->Run();
532 EXPECT_TRUE(g_callback_happened1); 527 EXPECT_TRUE(g_callback_happened1);
533 } 528 }
534 } 529 }
535 530
536 const size_t kNumWorkerThreads = 3;
537
538 // Fixture for tests requiring a worker pool. Includes a WaitableEvent so
539 // that cases may Wait() on one thread and Signal() (explicitly, or implicitly
540 // via helper methods) on another.
541 class TimerSequenceTest : public testing::Test {
542 public:
543 TimerSequenceTest()
544 : event_(false /* manual_reset */, false /* initially_signaled */) {}
545
546 void SetUp() override { ResetPools(); }
547
548 void TearDown() override {
549 pool1()->Shutdown();
550 pool2()->Shutdown();
551 }
552
553 // Block until Signal() is called on another thread.
554 void Wait() { event_.Wait(); }
555
556 void Signal() { event_.Signal(); }
557
558 // Helper to augment a task with a subsequent call to Signal().
559 base::Closure TaskWithSignal(const base::Closure& task) {
560 return base::Bind(&TimerSequenceTest::RunTaskAndSignal,
561 base::Unretained(this), task);
562 }
563
564 // Create the timer.
565 void CreateTimer() { timer_.reset(new base::OneShotTimer); }
566
567 // Schedule an event on the timer.
568 void StartTimer(TimeDelta delay, const base::Closure& task) {
569 timer_->Start(FROM_HERE, delay, task);
570 }
571
572 void SetTaskRunnerForTimer(SequencedTaskRunner* task_runner) {
573 timer_->SetTaskRunner(task_runner);
574 }
575
576 // Tell the timer to abandon the task.
577 void AbandonTask() {
578 ASSERT_TRUE(timer_->IsRunning());
579 // Reset() to call Timer::AbandonScheduledTask()
580 timer_->Reset();
581 ASSERT_TRUE(timer_->IsRunning());
582 timer_->Stop();
583 ASSERT_FALSE(timer_->IsRunning());
584 }
585
586 static void VerifyAffinity(SequencedTaskRunner* task_runner) {
587 ASSERT_TRUE(task_runner->RunsTasksOnCurrentThread());
588 }
589
590 // Delete the timer.
591 void DeleteTimer() { timer_.reset(); }
592
593 protected:
594 const scoped_refptr<base::SequencedWorkerPool>& pool1() {
595 return pool1_owner_->pool();
596 }
597 const scoped_refptr<base::SequencedWorkerPool>& pool2() {
598 return pool2_owner_->pool();
599 }
600
601 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut
602 // down, and creates a new instance.
603 void ResetPools() {
604 pool1_owner_.reset(
605 new base::SequencedWorkerPoolOwner(kNumWorkerThreads, "test1"));
606 pool2_owner_.reset(
607 new base::SequencedWorkerPoolOwner(kNumWorkerThreads, "test2"));
608 }
609
610 private:
611 void RunTaskAndSignal(const base::Closure& task) {
612 task.Run();
613 Signal();
614 }
615
616 base::WaitableEvent event_;
617
618 base::MessageLoop message_loop_;
619 scoped_ptr<base::SequencedWorkerPoolOwner> pool1_owner_;
620 scoped_ptr<base::SequencedWorkerPoolOwner> pool2_owner_;
621
622 scoped_ptr<base::OneShotTimer> timer_;
623
624 DISALLOW_COPY_AND_ASSIGN(TimerSequenceTest);
625 };
626
627 TEST_F(TimerSequenceTest, OneShotTimerTaskOnPoolThread) {
628 scoped_refptr<SequencedTaskRunner> task_runner =
629 pool1()->GetSequencedTaskRunner(pool1()->GetSequenceToken());
630
631 // Timer is created on this thread.
632 CreateTimer();
633
634 // Task will execute on a pool thread.
635 SetTaskRunnerForTimer(task_runner.get());
636 StartTimer(TimeDelta::FromMilliseconds(1),
637 base::Bind(&TimerSequenceTest::Signal, base::Unretained(this)));
638 Wait();
639
640 // Timer will be destroyed on this thread.
641 DeleteTimer();
642 }
643
644 TEST_F(TimerSequenceTest, OneShotTimerUsedOnPoolThread) {
645 scoped_refptr<SequencedTaskRunner> task_runner =
646 pool1()->GetSequencedTaskRunner(pool1()->GetSequenceToken());
647
648 // Timer is created on this thread.
649 CreateTimer();
650
651 // Task will be scheduled from a pool thread.
652 task_runner->PostTask(
653 FROM_HERE,
654 base::Bind(
655 &TimerSequenceTest::StartTimer, base::Unretained(this),
656 TimeDelta::FromMilliseconds(1),
657 base::Bind(&TimerSequenceTest::Signal, base::Unretained(this))));
658 Wait();
659
660 // Timer must be destroyed on pool thread, too.
661 task_runner->PostTask(
662 FROM_HERE, TaskWithSignal(base::Bind(&TimerSequenceTest::DeleteTimer,
663 base::Unretained(this))));
664 Wait();
665 }
666
667 TEST_F(TimerSequenceTest, OneShotTimerTwoPoolsAbandonTask) {
668 scoped_refptr<SequencedTaskRunner> task_runner1 =
669 pool1()->GetSequencedTaskRunner(pool1()->GetSequenceToken());
670 scoped_refptr<SequencedTaskRunner> task_runner2 =
671 pool2()->GetSequencedTaskRunner(pool2()->GetSequenceToken());
672
673 // Create timer on pool #1.
674 task_runner1->PostTask(
675 FROM_HERE, TaskWithSignal(base::Bind(&TimerSequenceTest::CreateTimer,
676 base::Unretained(this))));
677 Wait();
678
679 // Task will execute on a different pool (#2).
680 SetTaskRunnerForTimer(task_runner2.get());
681
682 // Task will be scheduled from pool #1.
683 task_runner1->PostTask(
684 FROM_HERE,
685 base::Bind(&TimerSequenceTest::StartTimer, base::Unretained(this),
686 TimeDelta::FromHours(1), base::Bind(&DoNothing)));
687
688 // Abandon task - must be called from scheduling pool (#1).
689 task_runner1->PostTask(
690 FROM_HERE, TaskWithSignal(base::Bind(&TimerSequenceTest::AbandonTask,
691 base::Unretained(this))));
692 Wait();
693
694 // Timer must be destroyed on the pool it was scheduled from (#1).
695 task_runner1->PostTask(
696 FROM_HERE, TaskWithSignal(base::Bind(&TimerSequenceTest::DeleteTimer,
697 base::Unretained(this))));
698 Wait();
699 }
700
701 TEST_F(TimerSequenceTest, OneShotTimerUsedAndTaskedOnDifferentPools) {
702 scoped_refptr<SequencedTaskRunner> task_runner1 =
703 pool1()->GetSequencedTaskRunner(pool1()->GetSequenceToken());
704 scoped_refptr<SequencedTaskRunner> task_runner2 =
705 pool2()->GetSequencedTaskRunner(pool2()->GetSequenceToken());
706
707 // Create timer on pool #1.
708 task_runner1->PostTask(
709 FROM_HERE, TaskWithSignal(base::Bind(&TimerSequenceTest::CreateTimer,
710 base::Unretained(this))));
711 Wait();
712
713 // Task will execute on a different pool (#2).
714 SetTaskRunnerForTimer(task_runner2.get());
715
716 // Task will be scheduled from pool #1.
717 task_runner1->PostTask(
718 FROM_HERE,
719 base::Bind(&TimerSequenceTest::StartTimer, base::Unretained(this),
720 TimeDelta::FromMilliseconds(1),
721 TaskWithSignal(base::Bind(&TimerSequenceTest::VerifyAffinity,
722 task_runner2))));
723
724 Wait();
725
726 // Timer must be destroyed on the pool it was scheduled from (#1).
727 task_runner1->PostTask(
728 FROM_HERE, TaskWithSignal(base::Bind(&TimerSequenceTest::DeleteTimer,
729 base::Unretained(this))));
730 Wait();
731 }
732
733 } // namespace 531 } // namespace
OLDNEW
« no previous file with comments | « base/timer/timer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698