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

Side by Side Diff: cc/test/ordered_simple_task_runner.cc

Issue 387493002: Fixing and enhancing OrderedSimpleTaskRunner to allow 100% deterministic tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing the gn build. Created 6 years, 4 months 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 | Annotate | Revision Log
OLDNEW
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 "cc/test/ordered_simple_task_runner.h" 5 #include "cc/test/ordered_simple_task_runner.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <deque> 8 #include <deque>
9 #include <sstream>
10 #include <string>
9 11
10 #include "base/logging.h" 12 #include "base/debug/trace_event.h"
13 #include "base/debug/trace_event_argument.h"
14 #include "base/strings/string_number_conversions.h"
15
16 #define TRACE_TASK(function, task) \
17 TRACE_EVENT_INSTANT1( \
18 "cc", function, TRACE_EVENT_SCOPE_THREAD, "task", TaskAsValue(task));
19
20 #define TRACE_TASK_RUN(function, tag, task)
11 21
12 namespace { 22 namespace {
13 23
14 bool TestPendingTaskComparator(const base::TestPendingTask& lhs, 24 bool TestPendingTaskComparator(const base::TestPendingTask& lhs,
15 const base::TestPendingTask& rhs) { 25 const base::TestPendingTask& rhs) {
16 return lhs.ShouldRunBefore(rhs); 26 return lhs.ShouldRunBefore(rhs);
17 } 27 }
18 28
29 void TaskAsValueInto(const base::TestPendingTask& task,
30 base::debug::TracedValue* state) {
31 state->SetInteger("run_at", task.GetTimeToRun().ToInternalValue());
32 state->SetString("posted_from", task.location.ToString());
19 } 33 }
20 34
35 scoped_refptr<base::debug::ConvertableToTraceFormat> TaskAsValue(
36 const base::TestPendingTask& task) {
37 scoped_refptr<base::debug::TracedValue> state =
38 new base::debug::TracedValue();
39 TaskAsValueInto(task, state);
40 return state;
41 }
42
43 } // namespace
44
21 namespace cc { 45 namespace cc {
22 46
23 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner() {} 47 void OrderedSimpleTaskRunner::SortTasks(
48 std::deque<base::TestPendingTask>* tasks) {
49 std::stable_sort(tasks->begin(), tasks->end(), TestPendingTaskComparator);
50 }
51
52 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner()
53 : advance_now_(true),
54 now_src_(TestNowSource::Create()),
55 inside_run_pending_tasks_(false) {
56 }
57
58 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner(
59 scoped_refptr<TestNowSource> now_src,
60 bool advance_now)
61 : advance_now_(advance_now),
62 now_src_(now_src),
63 inside_run_pending_tasks_(false) {
64 }
24 65
25 OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {} 66 OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {}
26 67
68 // base::TestSimpleTaskRunner implementation
69 bool OrderedSimpleTaskRunner::PostDelayedTask(
70 const tracked_objects::Location& from_here,
71 const base::Closure& task,
72 base::TimeDelta delay) {
73 DCHECK(thread_checker_.CalledOnValidThread());
74 base::TestPendingTask pt(
75 from_here, task, now_src_->Now(), delay, base::TestPendingTask::NESTABLE);
76
77 TRACE_TASK("OrderedSimpleTaskRunner::PostDelayedTask", pt);
78
79 pending_tasks_.push_back(pt);
80 SortTasks(&pending_tasks_);
81 return true;
82 }
83
84 bool OrderedSimpleTaskRunner::PostNonNestableDelayedTask(
85 const tracked_objects::Location& from_here,
86 const base::Closure& task,
87 base::TimeDelta delay) {
88 DCHECK(thread_checker_.CalledOnValidThread());
89 base::TestPendingTask pt(from_here,
90 task,
91 now_src_->Now(),
92 delay,
93 base::TestPendingTask::NON_NESTABLE);
94
95 TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt);
96
97 pending_tasks_.push_back(pt);
98 SortTasks(&pending_tasks_);
99 return true;
100 }
101
27 void OrderedSimpleTaskRunner::RunPendingTasks() { 102 void OrderedSimpleTaskRunner::RunPendingTasks() {
103 TRACE_EVENT1(
104 "cc", "OrderedSimpleTaskRunner::RunPendingTasks", "this", AsValue());
28 DCHECK(thread_checker_.CalledOnValidThread()); 105 DCHECK(thread_checker_.CalledOnValidThread());
106
107 if (inside_run_pending_tasks_)
108 return;
109 inside_run_pending_tasks_ = true;
110
29 // Swap with a local variable to avoid re-entrancy problems. 111 // Swap with a local variable to avoid re-entrancy problems.
30 std::deque<base::TestPendingTask> tasks_to_run; 112 std::deque<base::TestPendingTask> tasks_to_run;
31 tasks_to_run.swap(pending_tasks_); 113 tasks_to_run.swap(pending_tasks_);
32 std::stable_sort(tasks_to_run.begin(), 114
33 tasks_to_run.end(), 115 std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin();
34 TestPendingTaskComparator); 116 for (; it != tasks_to_run.end(); ++it) {
35 for (std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin(); 117 base::TimeTicks task_time = it->GetTimeToRun();
36 it != tasks_to_run.end(); ++it) { 118
37 it->task.Run(); 119 // Have new items been added to pending_tasks which need to run before this
120 // task?
121 if (pending_tasks_.size() > 0 &&
122 task_time > pending_tasks_.begin()->GetTimeToRun()) {
123 break;
124 }
125
126 // Is the task in the future?
127 if (task_time > now_src_->Now()) {
128 if (!advance_now_)
129 break;
130 else
131 now_src_->SetNow(task_time);
132 }
133
134 {
135 TRACE_EVENT1("cc",
136 "OrderedSimpleTaskRunner::RunPendingTasks running",
137 "task",
138 TaskAsValue(*it));
139 it->task.Run();
140 }
38 } 141 }
142
143 // Push any remaining tasks back into the pending queue
144 for (; it != tasks_to_run.end(); ++it) {
145 pending_tasks_.push_front(*it);
146 }
147 SortTasks(&pending_tasks_);
148
149 inside_run_pending_tasks_ = false;
150 }
151
152 base::TimeDelta OrderedSimpleTaskRunner::DelayToNextPendingTask() {
153 DCHECK(thread_checker_.CalledOnValidThread());
154
155 base::TimeDelta delay =
156 pending_tasks_.front().GetTimeToRun() - now_src_->Now();
157 if (delay > base::TimeDelta())
158 return delay;
159 return base::TimeDelta();
160 }
161
162 void OrderedSimpleTaskRunner::SetAutoAdvanceNowToPendingTasks(
163 bool advance_now) {
164 advance_now_ = advance_now;
165 }
166
167 // base::debug tracing functionality
168 scoped_refptr<base::debug::ConvertableToTraceFormat>
169 OrderedSimpleTaskRunner::AsValue() const {
170 scoped_refptr<base::debug::TracedValue> state =
171 new base::debug::TracedValue();
172 AsValueInto(state);
173 return state;
174 }
175
176 void OrderedSimpleTaskRunner::AsValueInto(
177 base::debug::TracedValue* state) const {
178 state->SetInteger("pending_tasks", pending_tasks_.size());
179 for (std::deque<base::TestPendingTask>::const_iterator it =
180 pending_tasks_.begin();
181 it != pending_tasks_.end();
182 ++it) {
183 state->BeginDictionary(
184 base::SizeTToString(std::distance(pending_tasks_.begin(), it)).c_str());
185 TaskAsValueInto(*it, state);
186 state->EndDictionary();
187 }
188 now_src_->AsValueInto(state);
39 } 189 }
40 190
41 } // namespace cc 191 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698