OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/cast/test/fake_single_thread_task_runner.h" | 5 #include "media/cast/test/fake_single_thread_task_runner.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/time/tick_clock.h" | 8 #include "base/time/tick_clock.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 | 10 |
11 namespace media { | 11 namespace media { |
12 namespace cast { | 12 namespace cast { |
13 namespace test { | 13 namespace test { |
14 | 14 |
15 FakeSingleThreadTaskRunner::FakeSingleThreadTaskRunner( | 15 FakeSingleThreadTaskRunner::FakeSingleThreadTaskRunner( |
16 base::SimpleTestTickClock* clock) | 16 base::SimpleTestTickClock* clock) |
17 : clock_(clock) {} | 17 : clock_(clock), |
18 fail_on_next_task_(false) {} | |
18 | 19 |
19 FakeSingleThreadTaskRunner::~FakeSingleThreadTaskRunner() {} | 20 FakeSingleThreadTaskRunner::~FakeSingleThreadTaskRunner() {} |
20 | 21 |
21 bool FakeSingleThreadTaskRunner::PostDelayedTask( | 22 bool FakeSingleThreadTaskRunner::PostDelayedTask( |
22 const tracked_objects::Location& from_here, | 23 const tracked_objects::Location& from_here, |
23 const base::Closure& task, | 24 const base::Closure& task, |
24 base::TimeDelta delay) { | 25 base::TimeDelta delay) { |
26 if (fail_on_next_task_) { | |
27 LOG(FATAL) << "Infinite task-add loop detected."; | |
28 } | |
25 EXPECT_GE(delay, base::TimeDelta()); | 29 EXPECT_GE(delay, base::TimeDelta()); |
26 PostedTask posed_task(from_here, | 30 PostedTask posed_task(from_here, |
27 task, | 31 task, |
28 clock_->NowTicks(), | 32 clock_->NowTicks(), |
29 delay, | 33 delay, |
30 base::TestPendingTask::NESTABLE); | 34 base::TestPendingTask::NESTABLE); |
31 | 35 |
32 tasks_.insert(std::make_pair(posed_task.GetTimeToRun(), posed_task)); | 36 tasks_.insert(std::make_pair(posed_task.GetTimeToRun(), posed_task)); |
33 return false; | 37 return false; |
34 } | 38 } |
35 | 39 |
36 bool FakeSingleThreadTaskRunner::RunsTasksOnCurrentThread() const { | 40 bool FakeSingleThreadTaskRunner::RunsTasksOnCurrentThread() const { |
37 return true; | 41 return true; |
38 } | 42 } |
39 | 43 |
40 void FakeSingleThreadTaskRunner::RunTasks() { | 44 void FakeSingleThreadTaskRunner::RunTasks() { |
41 while(true) { | 45 while (true) { |
42 // Run all tasks equal or older than current time. | 46 // Run all tasks equal or older than current time. |
43 std::multimap<base::TimeTicks, PostedTask>::iterator it = tasks_.begin(); | 47 std::multimap<base::TimeTicks, PostedTask>::iterator it = tasks_.begin(); |
44 if (it == tasks_.end()) | 48 if (it == tasks_.end()) |
45 return; // No more tasks. | 49 return; // No more tasks. |
46 | 50 |
47 PostedTask task = it->second; | 51 PostedTask task = it->second; |
48 if (clock_->NowTicks() < task.GetTimeToRun()) | 52 if (clock_->NowTicks() < task.GetTimeToRun()) |
49 return; | 53 return; |
50 | 54 |
51 tasks_.erase(it); | 55 tasks_.erase(it); |
52 task.task.Run(); | 56 task.task.Run(); |
53 } | 57 } |
54 } | 58 } |
55 | 59 |
60 void FakeSingleThreadTaskRunner::Sleep(base::TimeDelta t) { | |
61 base::TimeTicks run_until = clock_->NowTicks() + t; | |
62 while (1) { | |
63 // If we run more than 100000 iterations, we've probably | |
64 // hit some sort of case where a new task is posted every | |
65 // time that we invoke a task, and we can't make progress | |
66 // anymore. If that happens, set fail_on_next_task_ to true | |
67 // and throw an error when the next task is posted. | |
68 for (int i = 0; i < 100000; i++) { | |
Alpha Left Google
2014/05/16 18:20:51
Do we actually run into this problem? It is suspic
hubbe
2014/05/16 18:24:56
I did because of a bug in SkewedSingleThreadTaskRu
| |
69 // Run all tasks equal or older than current time. | |
70 std::multimap<base::TimeTicks, PostedTask>::iterator it = tasks_.begin(); | |
71 if (it == tasks_.end()) { | |
72 clock_->Advance(run_until - clock_->NowTicks()); | |
73 return; | |
74 } | |
75 | |
76 PostedTask task = it->second; | |
77 if (run_until < task.GetTimeToRun()) { | |
78 clock_->Advance(run_until - clock_->NowTicks()); | |
79 return; | |
80 } | |
81 | |
82 clock_->Advance(task.GetTimeToRun() - clock_->NowTicks()); | |
83 tasks_.erase(it); | |
84 task.task.Run(); | |
85 } | |
86 // Instead of failing immediately, we fail when the next task is | |
87 // added so that the backtrace will include the task that was added. | |
88 fail_on_next_task_ = true; | |
89 } | |
90 } | |
91 | |
56 bool FakeSingleThreadTaskRunner::PostNonNestableDelayedTask( | 92 bool FakeSingleThreadTaskRunner::PostNonNestableDelayedTask( |
57 const tracked_objects::Location& from_here, | 93 const tracked_objects::Location& from_here, |
58 const base::Closure& task, | 94 const base::Closure& task, |
59 base::TimeDelta delay) { | 95 base::TimeDelta delay) { |
60 NOTIMPLEMENTED(); | 96 NOTIMPLEMENTED(); |
61 return false; | 97 return false; |
62 } | 98 } |
63 | 99 |
64 } // namespace test | 100 } // namespace test |
65 } // namespace cast | 101 } // namespace cast |
66 } // namespace media | 102 } // namespace media |
OLD | NEW |