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

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

Issue 1433373003: Use SequenceChecker to allow Timer to run in SequencedWorkerPool (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments, tests 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
« base/timer/timer.h ('K') | « 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/callback.h"
5 #include "base/memory/scoped_ptr.h" 6 #include "base/memory/scoped_ptr.h"
6 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/test/sequenced_worker_pool_owner.h"
7 #include "base/test/test_simple_task_runner.h" 10 #include "base/test/test_simple_task_runner.h"
8 #include "base/timer/timer.h" 11 #include "base/timer/timer.h"
9 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
10 13
14 using base::SequencedTaskRunner;
11 using base::TimeDelta; 15 using base::TimeDelta;
12 using base::SingleThreadTaskRunner;
13 16
14 namespace { 17 namespace {
15 18
16 // The message loops on which each timer should be tested. 19 // The message loops on which each timer should be tested.
17 const base::MessageLoop::Type testing_message_loops[] = { 20 const base::MessageLoop::Type testing_message_loops[] = {
18 base::MessageLoop::TYPE_DEFAULT, 21 base::MessageLoop::TYPE_DEFAULT,
19 base::MessageLoop::TYPE_IO, 22 base::MessageLoop::TYPE_IO,
20 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop. 23 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
21 base::MessageLoop::TYPE_UI, 24 base::MessageLoop::TYPE_UI,
22 #endif 25 #endif
23 }; 26 };
24 27
25 const int kNumTestingMessageLoops = arraysize(testing_message_loops); 28 const int kNumTestingMessageLoops = arraysize(testing_message_loops);
26 29
27 class OneShotTimerTester { 30 class OneShotTimerTester {
28 public: 31 public:
29 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10) 32 explicit OneShotTimerTester(bool* did_run, unsigned milliseconds = 10)
30 : did_run_(did_run), 33 : did_run_(did_run),
31 delay_ms_(milliseconds), 34 delay_ms_(milliseconds),
32 quit_message_loop_(true) { 35 quit_message_loop_(true) {
33 } 36 }
34 37
35 void Start() { 38 void Start() {
36 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this, 39 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(delay_ms_), this,
37 &OneShotTimerTester::Run); 40 &OneShotTimerTester::Run);
38 } 41 }
39 42
40 void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) { 43 void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) {
41 quit_message_loop_ = false; 44 quit_message_loop_ = false;
42 timer_.SetTaskRunner(task_runner); 45 timer_.SetTaskRunner(task_runner);
43 } 46 }
44 47
45 private: 48 private:
46 void Run() { 49 void Run() {
47 *did_run_ = true; 50 *did_run_ = true;
48 if (quit_message_loop_) { 51 if (quit_message_loop_) {
49 base::MessageLoop::current()->QuitWhenIdle(); 52 base::MessageLoop::current()->QuitWhenIdle();
50 } 53 }
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10), 524 timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
522 base::Bind(&SetCallbackHappened1)); 525 base::Bind(&SetCallbackHappened1));
523 timer.Reset(); 526 timer.Reset();
524 // Since Reset happened before task ran, the user_task must not be cleared: 527 // Since Reset happened before task ran, the user_task must not be cleared:
525 ASSERT_FALSE(timer.user_task().is_null()); 528 ASSERT_FALSE(timer.user_task().is_null());
526 base::MessageLoop::current()->Run(); 529 base::MessageLoop::current()->Run();
527 EXPECT_TRUE(g_callback_happened1); 530 EXPECT_TRUE(g_callback_happened1);
528 } 531 }
529 } 532 }
530 533
534 const size_t kNumWorkerThreads = 3;
535
536 // Fixture for tests requiring a worker pool. Includes a WaitableEvent so
537 // that cases may Wait() on one thread and Signal() (explicitly, or implicitly
538 // via helper methods) on another.
539 class TimerSequenceTest : public testing::Test {
540 public:
541 TimerSequenceTest()
542 : event_(false /*manual_reset*/, true /*initially_signaled*/) {}
gab 2015/12/03 22:26:08 Add space padding in /* comment */
jsbell 2015/12/05 01:15:39 Done.
543
544 void SetUp() override { ResetPool(); }
545
546 void TearDown() override { pool()->Shutdown(); }
547
548 // Block until Signal() is called on another thread.
549 void Wait() { event_.Wait(); }
550
551 void Signal() { event_.Signal(); }
552
553 // Explicitly create the timer. Not done in the constructor so that test
554 // cases demonstrate creation on a specific thread.
555 void CreateTimer() { timer_.reset(new base::OneShotTimer); }
556
557 // Start the timer; when the timer fires it will Signal(), so Wait() can
558 // be called on another thread to await this.
559 void StartTimerWillSignal() {
560 timer_->Start(FROM_HERE, TimeDelta::FromMilliseconds(1), this,
561 &TimerSequenceTest::Signal);
562 }
563
564 // Delete the timer then Signal() so that this can be posted as a task
565 // to another thread and the poster can Wait().
566 void DeleteTimerAndSignal() {
567 timer_.reset();
568 Signal();
569 }
570
571 protected:
572 const scoped_refptr<base::SequencedWorkerPool>& pool() {
573 return pool_owner_->pool();
574 }
575
576 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut
577 // down, and creates a new instance.
578 void ResetPool() {
579 pool_owner_.reset(
580 new base::SequencedWorkerPoolOwner(kNumWorkerThreads, "test"));
581 }
582
583 scoped_ptr<base::OneShotTimer> timer_;
584
585 private:
586 base::WaitableEvent event_;
587
588 base::MessageLoop message_loop_;
589 scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
590 };
gab 2015/12/03 22:26:08 DISALLOW_COPY_AND_ASSIGN
jsbell 2015/12/05 01:15:39 Done.
591
592 TEST_F(TimerSequenceTest, OneShotTimerTaskOnPoolThread) {
593 scoped_refptr<base::SequencedTaskRunner> task_runner =
594 pool()->GetSequencedTaskRunner(pool()->GetSequenceToken());
595
596 // Timer is created on this thread.
597 CreateTimer();
598
599 // Task will execute on a pool thread.
600 timer_->SetTaskRunner(task_runner.get());
601 StartTimerWillSignal();
602 Wait();
603
604 // Timer will be destroyed on this thread.
605 timer_.reset();
606 }
607
608 TEST_F(TimerSequenceTest, OneShotTimerUsedOnPoolThread) {
609 scoped_refptr<base::SequencedTaskRunner> task_runner =
610 pool()->GetSequencedTaskRunner(pool()->GetSequenceToken());
611
612 // Timer is created on this thread.
613 CreateTimer();
614
615 // Task will execute on a pool thread.
616 task_runner->PostTask(FROM_HERE,
617 base::Bind(&TimerSequenceTest::StartTimerWillSignal,
618 base::Unretained(this)));
619 Wait();
620
621 // Timer must be destroyed on pool thread, too.
622 task_runner->PostTask(FROM_HERE,
623 base::Bind(&TimerSequenceTest::DeleteTimerAndSignal,
624 base::Unretained(this)));
625 Wait();
626 }
627
gab 2015/12/03 22:26:09 Feels a test that would: 1) Create a |timer| from
jsbell 2015/12/05 01:15:39 Those sound great - done and done. Any others?
531 } // namespace 628 } // namespace
OLDNEW
« base/timer/timer.h ('K') | « base/timer/timer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698