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 "cc/test/ordered_simple_task_runner.h" | 5 #include "cc/test/ordered_simple_task_runner.h" |
6 #include "base/debug/trace_event.h" | |
6 | 7 |
7 #include <algorithm> | 8 #include <algorithm> |
8 #include <deque> | 9 #include <deque> |
9 | 10 |
10 #include "base/logging.h" | |
11 | |
12 namespace { | 11 namespace { |
13 | 12 |
14 bool TestPendingTaskComparator(const base::TestPendingTask& lhs, | 13 bool TestPendingTaskComparator(const base::TestPendingTask& lhs, |
15 const base::TestPendingTask& rhs) { | 14 const base::TestPendingTask& rhs) { |
16 return lhs.ShouldRunBefore(rhs); | 15 return lhs.ShouldRunBefore(rhs); |
17 } | 16 } |
18 | 17 |
19 } | 18 } |
20 | 19 |
21 namespace cc { | 20 namespace cc { |
22 | 21 |
23 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner() {} | 22 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner(bool advance_now) |
23 : advance_now_(advance_now), now_(), inside_run_pending_tasks_(false) { | |
24 } | |
24 | 25 |
25 OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {} | 26 OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {} |
26 | 27 |
28 void OrderedSimpleTaskRunner::SortTasks( | |
29 std::deque<base::TestPendingTask>& tasks) { | |
30 std::stable_sort(tasks.begin(), tasks.end(), TestPendingTaskComparator); | |
31 } | |
32 | |
33 bool OrderedSimpleTaskRunner::PostDelayedTask( | |
34 const tracked_objects::Location& from_here, | |
35 const base::Closure& task, | |
36 base::TimeDelta delay) { | |
37 DCHECK(thread_checker_.CalledOnValidThread()); | |
38 base::TestPendingTask pt( | |
39 from_here, task, Now(), delay, base::TestPendingTask::NESTABLE); | |
40 TRACE_EVENT_INSTANT2("cc", | |
brianderson
2014/07/17 05:26:03
What categories do other cc testing files use?
| |
41 "OrderedSimpleTaskRunner::PostDelayedTask", | |
42 TRACE_EVENT_SCOPE_THREAD, | |
43 "RunAt", | |
44 pt.GetTimeToRun(), | |
45 "Function", | |
46 pt.location.ToString()); | |
47 pending_tasks_.push_back(pt); | |
48 SortTasks(pending_tasks_); | |
49 return true; | |
50 } | |
51 | |
52 bool OrderedSimpleTaskRunner::PostNonNestableDelayedTask( | |
53 const tracked_objects::Location& from_here, | |
54 const base::Closure& task, | |
55 base::TimeDelta delay) { | |
56 DCHECK(thread_checker_.CalledOnValidThread()); | |
57 base::TestPendingTask pt( | |
58 from_here, task, Now(), delay, base::TestPendingTask::NON_NESTABLE); | |
59 TRACE_EVENT_INSTANT2("cc", | |
60 "OrderedSimpleTaskRunner::PostNonNestableDelayedTask", | |
61 TRACE_EVENT_SCOPE_THREAD, | |
62 "RunAt", | |
63 pt.GetTimeToRun(), | |
64 "Function", | |
65 pt.location.ToString()); | |
66 pending_tasks_.push_back(pt); | |
67 SortTasks(pending_tasks_); | |
68 return true; | |
69 } | |
70 | |
27 void OrderedSimpleTaskRunner::RunPendingTasks() { | 71 void OrderedSimpleTaskRunner::RunPendingTasks() { |
28 DCHECK(thread_checker_.CalledOnValidThread()); | 72 DCHECK(thread_checker_.CalledOnValidThread()); |
73 | |
74 if (inside_run_pending_tasks_) | |
75 return; | |
76 inside_run_pending_tasks_ = true; | |
77 | |
29 // Swap with a local variable to avoid re-entrancy problems. | 78 // Swap with a local variable to avoid re-entrancy problems. |
30 std::deque<base::TestPendingTask> tasks_to_run; | 79 std::deque<base::TestPendingTask> tasks_to_run; |
31 tasks_to_run.swap(pending_tasks_); | 80 tasks_to_run.swap(pending_tasks_); |
32 std::stable_sort(tasks_to_run.begin(), | 81 |
33 tasks_to_run.end(), | 82 TRACE_EVENT_INSTANT1("cc", |
34 TestPendingTaskComparator); | 83 "OrderedSimpleTaskRunner::RunPendingTasks pendingTask", |
84 TRACE_EVENT_SCOPE_THREAD, | |
85 "waiting", | |
86 tasks_to_run.size()); | |
35 for (std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin(); | 87 for (std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin(); |
36 it != tasks_to_run.end(); ++it) { | 88 it != tasks_to_run.end(); |
37 it->task.Run(); | 89 ++it) { |
90 TRACE_EVENT_INSTANT2("cc", | |
91 "OrderedSimpleTaskRunner::RunPendingTasks pendingTask", | |
92 TRACE_EVENT_SCOPE_THREAD, | |
93 "RunAt", | |
94 it->GetTimeToRun(), | |
95 "Function", | |
96 it->location.ToString()); | |
38 } | 97 } |
98 | |
99 std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin(); | |
100 for (; it != tasks_to_run.end(); ++it) { | |
101 base::TimeTicks task_time = it->GetTimeToRun(); | |
102 | |
103 // Have new items been added to pending_tasks which need to run before this | |
104 // task? | |
105 if (pending_tasks_.size() > 0 && | |
106 task_time > pending_tasks_.begin()->GetTimeToRun()) { | |
107 break; | |
brianderson
2014/07/17 05:26:03
So this function doesn't run all pending tasks if
mithro-old
2014/07/17 06:51:58
See the discussion on the https://codereview.chrom
| |
108 } | |
109 | |
110 // Is the task in the future? | |
111 if (task_time > Now()) { | |
112 if (!advance_now_) | |
113 break; | |
114 else | |
115 SetNow(task_time); | |
116 } | |
117 | |
118 { | |
119 TRACE_EVENT2("cc", | |
120 "OrderedSimpleTaskRunner::RunPendingTasks running", | |
121 "RunAt", | |
122 it->GetTimeToRun(), | |
123 "Function", | |
124 it->location.ToString()); | |
125 it->task.Run(); | |
126 } | |
127 } | |
128 | |
129 // Push any remaining tasks back into the pending queue | |
130 for (; it != tasks_to_run.end(); ++it) { | |
131 TRACE_EVENT_INSTANT2( | |
132 "cc", | |
133 "OrderedSimpleTaskRunner::RunPendingTasks requeuing pendingTask", | |
134 TRACE_EVENT_SCOPE_THREAD, | |
135 "RunAt", | |
136 it->GetTimeToRun(), | |
137 "Function", | |
138 it->location.ToString()); | |
139 pending_tasks_.push_front(*it); | |
140 } | |
141 std::stable_sort( | |
142 pending_tasks_.begin(), pending_tasks_.end(), TestPendingTaskComparator); | |
143 | |
144 inside_run_pending_tasks_ = false; | |
145 } | |
146 | |
147 base::TimeTicks OrderedSimpleTaskRunner::Now() { | |
148 return now_; | |
149 } | |
150 | |
151 base::TimeDelta OrderedSimpleTaskRunner::DelayToNextPendingTask() { | |
152 DCHECK(thread_checker_.CalledOnValidThread()); | |
153 | |
154 base::TimeDelta delay = pending_tasks_.front().GetTimeToRun() - Now(); | |
155 if (delay > base::TimeDelta()) | |
156 return delay; | |
157 return base::TimeDelta(); | |
158 } | |
159 | |
160 void OrderedSimpleTaskRunner::SetAutoAdvanceNowToPendingTasks( | |
161 bool advance_now) { | |
162 advance_now_ = advance_now; | |
163 } | |
164 | |
165 void OrderedSimpleTaskRunner::SetNow(base::TimeTicks time) { | |
166 TRACE_EVENT2( | |
167 "cc", "OrderedSimpleTaskRunner::SetNow", "current", time, "new", time); | |
168 DCHECK(time >= now_); | |
169 now_ = time; | |
39 } | 170 } |
40 | 171 |
41 } // namespace cc | 172 } // namespace cc |
OLD | NEW |