OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/scheduler/base/task_queue_impl.h" | 5 #include "components/scheduler/base/task_queue_impl.h" |
6 | 6 |
7 #include "components/scheduler/base/delayed_task_delegate.h" | |
7 #include "components/scheduler/base/task_queue_manager.h" | 8 #include "components/scheduler/base/task_queue_manager.h" |
8 #include "components/scheduler/base/task_queue_manager_delegate.h" | 9 #include "components/scheduler/base/task_queue_manager_delegate.h" |
9 | 10 |
10 namespace scheduler { | 11 namespace scheduler { |
11 namespace internal { | 12 namespace internal { |
12 | 13 |
13 TaskQueueImpl::TaskQueueImpl( | 14 TaskQueueImpl::TaskQueueImpl( |
14 TaskQueueManager* task_queue_manager, | 15 TaskQueueManager* task_queue_manager, |
16 const scoped_refptr<DelayedTaskDelegate>& delayed_task_delegate, | |
15 const Spec& spec, | 17 const Spec& spec, |
16 const char* disabled_by_default_tracing_category, | 18 const char* disabled_by_default_tracing_category, |
17 const char* disabled_by_default_verbose_tracing_category) | 19 const char* disabled_by_default_verbose_tracing_category) |
18 : thread_id_(base::PlatformThread::CurrentId()), | 20 : thread_id_(base::PlatformThread::CurrentId()), |
19 any_thread_(task_queue_manager, spec.pump_policy), | 21 any_thread_(task_queue_manager, spec.pump_policy, delayed_task_delegate), |
20 name_(spec.name), | 22 name_(spec.name), |
21 disabled_by_default_tracing_category_( | 23 disabled_by_default_tracing_category_( |
22 disabled_by_default_tracing_category), | 24 disabled_by_default_tracing_category), |
23 disabled_by_default_verbose_tracing_category_( | 25 disabled_by_default_verbose_tracing_category_( |
24 disabled_by_default_verbose_tracing_category), | 26 disabled_by_default_verbose_tracing_category), |
25 main_thread_only_(task_queue_manager), | 27 main_thread_only_(task_queue_manager), |
26 wakeup_policy_(spec.wakeup_policy), | 28 wakeup_policy_(spec.wakeup_policy), |
27 should_monitor_quiescence_(spec.should_monitor_quiescence), | 29 should_monitor_quiescence_(spec.should_monitor_quiescence), |
28 should_notify_observers_(spec.should_notify_observers) {} | 30 should_notify_observers_(spec.should_notify_observers) {} |
29 | 31 |
(...skipping 16 matching lines...) Expand all Loading... | |
46 int sequence_number, | 48 int sequence_number, |
47 bool nestable) | 49 bool nestable) |
48 : PendingTask(posted_from, task, base::TimeTicks(), nestable), | 50 : PendingTask(posted_from, task, base::TimeTicks(), nestable), |
49 #ifndef NDEBUG | 51 #ifndef NDEBUG |
50 enqueue_order_set_(false), | 52 enqueue_order_set_(false), |
51 #endif | 53 #endif |
52 enqueue_order_(0) { | 54 enqueue_order_(0) { |
53 sequence_num = sequence_number; | 55 sequence_num = sequence_number; |
54 } | 56 } |
55 | 57 |
56 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, | 58 TaskQueueImpl::AnyThread::AnyThread( |
57 PumpPolicy pump_policy) | 59 TaskQueueManager* task_queue_manager, |
58 : task_queue_manager(task_queue_manager), pump_policy(pump_policy) {} | 60 PumpPolicy pump_policy, |
61 const scoped_refptr<DelayedTaskDelegate>& delayed_task_delegate) | |
62 : task_queue_manager(task_queue_manager), | |
63 pump_policy(pump_policy), | |
64 delayed_task_delegate(delayed_task_delegate) {} | |
59 | 65 |
60 TaskQueueImpl::AnyThread::~AnyThread() {} | 66 TaskQueueImpl::AnyThread::~AnyThread() {} |
61 | 67 |
62 TaskQueueImpl::MainThreadOnly::MainThreadOnly( | 68 TaskQueueImpl::MainThreadOnly::MainThreadOnly( |
63 TaskQueueManager* task_queue_manager) | 69 TaskQueueManager* task_queue_manager) |
64 : task_queue_manager(task_queue_manager), | 70 : task_queue_manager(task_queue_manager), |
65 set_index(0) {} | 71 set_index(0) {} |
66 | 72 |
67 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} | 73 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} |
68 | 74 |
69 void TaskQueueImpl::UnregisterTaskQueue() { | 75 void TaskQueueImpl::UnregisterTaskQueue() { |
70 base::AutoLock lock(any_thread_lock_); | 76 base::AutoLock lock(any_thread_lock_); |
71 if (!any_thread().task_queue_manager) | 77 if (!any_thread().task_queue_manager) |
72 return; | 78 return; |
79 | |
80 any_thread().delayed_task_delegate->CancelDelayedWork(this); | |
81 any_thread().delayed_task_delegate = scoped_refptr<DelayedTaskDelegate>(); | |
Sami
2015/11/17 10:31:06
nit: I think there's a release() or reset() for th
alex clarke (OOO till 29th)
2015/11/18 15:30:15
I can't see anything like that on scoped_refptr
| |
73 any_thread().task_queue_manager->UnregisterTaskQueue(this); | 82 any_thread().task_queue_manager->UnregisterTaskQueue(this); |
74 | 83 |
75 any_thread().task_queue_manager = nullptr; | 84 any_thread().task_queue_manager = nullptr; |
76 main_thread_only().task_queue_manager = nullptr; | 85 main_thread_only().task_queue_manager = nullptr; |
77 any_thread().delayed_task_queue = std::priority_queue<Task>(); | 86 any_thread().delayed_task_queue = std::priority_queue<Task>(); |
78 any_thread().incoming_queue = std::queue<Task>(); | 87 any_thread().incoming_queue = std::queue<Task>(); |
79 main_thread_only().work_queue = std::queue<Task>(); | 88 main_thread_only().work_queue = std::queue<Task>(); |
80 } | 89 } |
81 | 90 |
82 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { | 91 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { |
(...skipping 14 matching lines...) Expand all Loading... | |
97 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); | 106 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); |
98 } | 107 } |
99 | 108 |
100 bool TaskQueueImpl::PostDelayedTaskAt( | 109 bool TaskQueueImpl::PostDelayedTaskAt( |
101 const tracked_objects::Location& from_here, | 110 const tracked_objects::Location& from_here, |
102 const base::Closure& task, | 111 const base::Closure& task, |
103 base::TimeTicks desired_run_time) { | 112 base::TimeTicks desired_run_time) { |
104 base::AutoLock lock(any_thread_lock_); | 113 base::AutoLock lock(any_thread_lock_); |
105 if (!any_thread().task_queue_manager) | 114 if (!any_thread().task_queue_manager) |
106 return false; | 115 return false; |
107 LazyNow lazy_now(any_thread().task_queue_manager->delegate().get()); | 116 any_thread().delayed_task_delegate->InvalidateNowCache(); |
108 return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, | 117 return PostDelayedTaskLocked(from_here, task, desired_run_time, |
109 TaskType::NORMAL); | 118 TaskType::NORMAL); |
110 } | 119 } |
111 | 120 |
112 bool TaskQueueImpl::PostDelayedTaskImpl( | 121 bool TaskQueueImpl::PostDelayedTaskImpl( |
113 const tracked_objects::Location& from_here, | 122 const tracked_objects::Location& from_here, |
114 const base::Closure& task, | 123 const base::Closure& task, |
115 base::TimeDelta delay, | 124 base::TimeDelta delay, |
116 TaskType task_type) { | 125 TaskType task_type) { |
117 base::AutoLock lock(any_thread_lock_); | 126 base::AutoLock lock(any_thread_lock_); |
118 if (!any_thread().task_queue_manager) | 127 if (!any_thread().task_queue_manager) |
119 return false; | 128 return false; |
120 LazyNow lazy_now(any_thread().task_queue_manager->delegate().get()); | |
121 base::TimeTicks desired_run_time; | 129 base::TimeTicks desired_run_time; |
130 any_thread().delayed_task_delegate->InvalidateNowCache(); | |
122 if (delay > base::TimeDelta()) | 131 if (delay > base::TimeDelta()) |
123 desired_run_time = lazy_now.Now() + delay; | 132 desired_run_time = any_thread().delayed_task_delegate->CachedNow() + delay; |
124 return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, | 133 return PostDelayedTaskLocked(from_here, task, desired_run_time, task_type); |
125 task_type); | |
126 } | 134 } |
127 | 135 |
128 bool TaskQueueImpl::PostDelayedTaskLocked( | 136 bool TaskQueueImpl::PostDelayedTaskLocked( |
129 LazyNow* lazy_now, | |
130 const tracked_objects::Location& from_here, | 137 const tracked_objects::Location& from_here, |
131 const base::Closure& task, | 138 const base::Closure& task, |
132 base::TimeTicks desired_run_time, | 139 base::TimeTicks desired_run_time, |
133 TaskType task_type) { | 140 TaskType task_type) { |
134 DCHECK(any_thread().task_queue_manager); | 141 DCHECK(any_thread().task_queue_manager); |
135 Task pending_task(from_here, task, | 142 Task pending_task(from_here, task, |
136 any_thread().task_queue_manager->GetNextSequenceNumber(), | 143 any_thread().task_queue_manager->GetNextSequenceNumber(), |
137 task_type != TaskType::NON_NESTABLE); | 144 task_type != TaskType::NON_NESTABLE); |
138 any_thread().task_queue_manager->DidQueueTask(pending_task); | 145 any_thread().task_queue_manager->DidQueueTask(pending_task); |
139 | 146 |
140 if (!desired_run_time.is_null()) { | 147 if (!desired_run_time.is_null()) { |
141 pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time); | 148 pending_task.delayed_run_time = std::max( |
149 any_thread().delayed_task_delegate->CachedNow(), desired_run_time); | |
142 // TODO(alexclarke): consider emplace() when C++11 library features allowed. | 150 // TODO(alexclarke): consider emplace() when C++11 library features allowed. |
143 any_thread().delayed_task_queue.push(pending_task); | 151 any_thread().delayed_task_queue.push(pending_task); |
144 TraceQueueSize(true); | 152 TraceQueueSize(true); |
145 // Schedule a later call to MoveReadyDelayedTasksToIncomingQueue. | 153 // Schedule a later call to MoveReadyDelayedTasksToIncomingQueue. |
146 any_thread().task_queue_manager->ScheduleDelayedWork(this, desired_run_time, | 154 any_thread().delayed_task_delegate->ScheduleDelayedWork(this, |
147 lazy_now); | 155 desired_run_time); |
148 return true; | 156 return true; |
149 } | 157 } |
150 pending_task.set_enqueue_order(pending_task.sequence_num); | 158 pending_task.set_enqueue_order(pending_task.sequence_num); |
151 EnqueueTaskLocked(pending_task); | 159 EnqueueTaskLocked(pending_task); |
152 return true; | 160 return true; |
153 } | 161 } |
154 | 162 |
155 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) { | 163 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue() { |
156 base::AutoLock lock(any_thread_lock_); | 164 base::AutoLock lock(any_thread_lock_); |
157 if (!any_thread().task_queue_manager) | 165 if (!any_thread().task_queue_manager) |
158 return; | 166 return; |
159 | 167 |
160 MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); | 168 MoveReadyDelayedTasksToIncomingQueueLocked(); |
161 } | 169 } |
162 | 170 |
163 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked( | 171 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked() { |
164 LazyNow* lazy_now) { | |
165 // Enqueue all delayed tasks that should be running now. | 172 // Enqueue all delayed tasks that should be running now. |
166 while (!any_thread().delayed_task_queue.empty() && | 173 while (!any_thread().delayed_task_queue.empty() && |
167 any_thread().delayed_task_queue.top().delayed_run_time <= | 174 any_thread().delayed_task_queue.top().delayed_run_time <= |
168 lazy_now->Now()) { | 175 any_thread().delayed_task_delegate->CachedNow()) { |
169 // TODO(alexclarke): consider std::move() when allowed. | 176 // TODO(alexclarke): consider std::move() when allowed. |
170 EnqueueDelayedTaskLocked(any_thread().delayed_task_queue.top()); | 177 EnqueueDelayedTaskLocked(any_thread().delayed_task_queue.top()); |
171 any_thread().delayed_task_queue.pop(); | 178 any_thread().delayed_task_queue.pop(); |
172 } | 179 } |
173 TraceQueueSize(true); | 180 TraceQueueSize(true); |
174 } | 181 } |
175 | 182 |
176 bool TaskQueueImpl::IsQueueEnabled() const { | 183 bool TaskQueueImpl::IsQueueEnabled() const { |
177 if (!main_thread_only().task_queue_manager) | 184 if (!main_thread_only().task_queue_manager) |
178 return false; | 185 return false; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 bool TaskQueueImpl::NextPendingDelayedTaskRunTime( | 232 bool TaskQueueImpl::NextPendingDelayedTaskRunTime( |
226 base::TimeTicks* next_pending_delayed_task) { | 233 base::TimeTicks* next_pending_delayed_task) { |
227 base::AutoLock lock(any_thread_lock_); | 234 base::AutoLock lock(any_thread_lock_); |
228 if (any_thread().delayed_task_queue.empty()) | 235 if (any_thread().delayed_task_queue.empty()) |
229 return false; | 236 return false; |
230 *next_pending_delayed_task = | 237 *next_pending_delayed_task = |
231 any_thread().delayed_task_queue.top().delayed_run_time; | 238 any_thread().delayed_task_queue.top().delayed_run_time; |
232 return true; | 239 return true; |
233 } | 240 } |
234 | 241 |
235 void TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now, | 242 void TaskQueueImpl::UpdateWorkQueue(bool should_trigger_wakeup, |
236 bool should_trigger_wakeup, | |
237 const Task* previous_task) { | 243 const Task* previous_task) { |
238 DCHECK(main_thread_only().work_queue.empty()); | 244 DCHECK(main_thread_only().work_queue.empty()); |
239 base::AutoLock lock(any_thread_lock_); | 245 base::AutoLock lock(any_thread_lock_); |
240 if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) | 246 if (!ShouldAutoPumpQueueLocked(should_trigger_wakeup, previous_task)) |
241 return; | 247 return; |
242 MoveReadyDelayedTasksToIncomingQueueLocked(lazy_now); | 248 MoveReadyDelayedTasksToIncomingQueueLocked(); |
243 std::swap(main_thread_only().work_queue, any_thread().incoming_queue); | 249 std::swap(main_thread_only().work_queue, any_thread().incoming_queue); |
244 // |any_thread().incoming_queue| is now empty so | 250 // |any_thread().incoming_queue| is now empty so |
245 // TaskQueueManager::UpdateQueues no longer needs to consider | 251 // TaskQueueManager::UpdateQueues no longer needs to consider |
246 // this queue for reloading. | 252 // this queue for reloading. |
247 any_thread().task_queue_manager->UnregisterAsUpdatableTaskQueue(this); | 253 any_thread().task_queue_manager->UnregisterAsUpdatableTaskQueue(this); |
248 if (!main_thread_only().work_queue.empty()) { | 254 if (!main_thread_only().work_queue.empty()) { |
249 DCHECK(any_thread().task_queue_manager); | 255 DCHECK(any_thread().task_queue_manager); |
250 any_thread().task_queue_manager->selector_.GetTaskQueueSets()->OnPushQueue( | 256 any_thread().task_queue_manager->selector_.GetTaskQueueSets()->OnPushQueue( |
251 this); | 257 this); |
252 TraceQueueSize(true); | 258 TraceQueueSize(true); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 any_thread().pump_policy != PumpPolicy::AUTO) { | 321 any_thread().pump_policy != PumpPolicy::AUTO) { |
316 PumpQueueLocked(); | 322 PumpQueueLocked(); |
317 } | 323 } |
318 any_thread().pump_policy = pump_policy; | 324 any_thread().pump_policy = pump_policy; |
319 } | 325 } |
320 | 326 |
321 void TaskQueueImpl::PumpQueueLocked() { | 327 void TaskQueueImpl::PumpQueueLocked() { |
322 if (!any_thread().task_queue_manager) | 328 if (!any_thread().task_queue_manager) |
323 return; | 329 return; |
324 | 330 |
325 LazyNow lazy_now(any_thread().task_queue_manager->delegate().get()); | 331 any_thread().delayed_task_delegate->InvalidateNowCache(); |
326 MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); | 332 MoveReadyDelayedTasksToIncomingQueueLocked(); |
327 | 333 |
328 bool was_empty = main_thread_only().work_queue.empty(); | 334 bool was_empty = main_thread_only().work_queue.empty(); |
329 while (!any_thread().incoming_queue.empty()) { | 335 while (!any_thread().incoming_queue.empty()) { |
330 // TODO(alexclarke): consider std::move() when allowed. | 336 // TODO(alexclarke): consider std::move() when allowed. |
331 main_thread_only().work_queue.push(any_thread().incoming_queue.front()); | 337 main_thread_only().work_queue.push(any_thread().incoming_queue.front()); |
332 any_thread().incoming_queue.pop(); | 338 any_thread().incoming_queue.pop(); |
333 } | 339 } |
334 // |incoming_queue| is now empty so TaskQueueManager::UpdateQueues no longer | 340 // |incoming_queue| is now empty so TaskQueueManager::UpdateQueues no longer |
335 // needs to consider this queue for reloading. | 341 // needs to consider this queue for reloading. |
336 any_thread().task_queue_manager->UnregisterAsUpdatableTaskQueue(this); | 342 any_thread().task_queue_manager->UnregisterAsUpdatableTaskQueue(this); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
509 state->SetInteger("enqueue_order", task.enqueue_order()); | 515 state->SetInteger("enqueue_order", task.enqueue_order()); |
510 state->SetInteger("sequence_num", task.sequence_num); | 516 state->SetInteger("sequence_num", task.sequence_num); |
511 state->SetBoolean("nestable", task.nestable); | 517 state->SetBoolean("nestable", task.nestable); |
512 state->SetBoolean("is_high_res", task.is_high_res); | 518 state->SetBoolean("is_high_res", task.is_high_res); |
513 state->SetDouble( | 519 state->SetDouble( |
514 "delayed_run_time", | 520 "delayed_run_time", |
515 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); | 521 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); |
516 state->EndDictionary(); | 522 state->EndDictionary(); |
517 } | 523 } |
518 | 524 |
525 size_t TaskQueueImpl::IncommingQueueSizeForTest() const { | |
526 base::AutoLock lock(any_thread_lock_); | |
527 return any_thread().incoming_queue.size(); | |
528 } | |
529 | |
519 } // namespace internal | 530 } // namespace internal |
520 } // namespace scheduler | 531 } // namespace scheduler |
OLD | NEW |