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 "components/scheduler/base/task_queue_manager.h" | 5 #include "components/scheduler/base/task_queue_manager.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/time/default_tick_clock.h" | |
12 #include "components/scheduler/base/lazy_now.h" | 11 #include "components/scheduler/base/lazy_now.h" |
13 #include "components/scheduler/base/nestable_single_thread_task_runner.h" | |
14 #include "components/scheduler/base/task_queue_impl.h" | 12 #include "components/scheduler/base/task_queue_impl.h" |
| 13 #include "components/scheduler/base/task_queue_manager_delegate.h" |
15 #include "components/scheduler/base/task_queue_selector.h" | 14 #include "components/scheduler/base/task_queue_selector.h" |
16 #include "components/scheduler/base/task_queue_sets.h" | 15 #include "components/scheduler/base/task_queue_sets.h" |
17 | 16 |
18 namespace { | 17 namespace { |
19 const int64_t kMaxTimeTicks = std::numeric_limits<int64>::max(); | 18 const int64_t kMaxTimeTicks = std::numeric_limits<int64>::max(); |
20 } | 19 } |
21 | 20 |
22 namespace scheduler { | 21 namespace scheduler { |
23 | 22 |
24 TaskQueueManager::TaskQueueManager( | 23 TaskQueueManager::TaskQueueManager( |
25 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner, | 24 scoped_refptr<TaskQueueManagerDelegate> delegate, |
26 const char* tracing_category, | 25 const char* tracing_category, |
27 const char* disabled_by_default_tracing_category, | 26 const char* disabled_by_default_tracing_category, |
28 const char* disabled_by_default_verbose_tracing_category) | 27 const char* disabled_by_default_verbose_tracing_category) |
29 : main_task_runner_(main_task_runner), | 28 : delegate_(delegate), |
30 task_was_run_on_quiescence_monitored_queue_(false), | 29 task_was_run_on_quiescence_monitored_queue_(false), |
31 pending_dowork_count_(0), | 30 pending_dowork_count_(0), |
32 work_batch_size_(1), | 31 work_batch_size_(1), |
33 time_source_(new base::DefaultTickClock), | |
34 tracing_category_(tracing_category), | 32 tracing_category_(tracing_category), |
35 disabled_by_default_tracing_category_( | 33 disabled_by_default_tracing_category_( |
36 disabled_by_default_tracing_category), | 34 disabled_by_default_tracing_category), |
37 disabled_by_default_verbose_tracing_category_( | 35 disabled_by_default_verbose_tracing_category_( |
38 disabled_by_default_verbose_tracing_category), | 36 disabled_by_default_verbose_tracing_category), |
39 observer_(nullptr), | 37 observer_(nullptr), |
40 deletion_sentinel_(new DeletionSentinel()), | 38 deletion_sentinel_(new DeletionSentinel()), |
41 weak_factory_(this) { | 39 weak_factory_(this) { |
42 DCHECK(main_task_runner->RunsTasksOnCurrentThread()); | 40 DCHECK(delegate->RunsTasksOnCurrentThread()); |
43 TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category, | 41 TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category, |
44 "TaskQueueManager", this); | 42 "TaskQueueManager", this); |
45 selector_.SetTaskQueueSelectorObserver(this); | 43 selector_.SetTaskQueueSelectorObserver(this); |
46 | 44 |
47 decrement_pending_and_do_work_closure_ = | 45 decrement_pending_and_do_work_closure_ = |
48 base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true); | 46 base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), true); |
49 do_work_closure_ = | 47 do_work_closure_ = |
50 base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false); | 48 base::Bind(&TaskQueueManager::DoWork, weak_factory_.GetWeakPtr(), false); |
51 } | 49 } |
52 | 50 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 newly_updatable_.pop_back(); | 164 newly_updatable_.pop_back(); |
167 } | 165 } |
168 } | 166 } |
169 | 167 |
170 void TaskQueueManager::UpdateWorkQueues( | 168 void TaskQueueManager::UpdateWorkQueues( |
171 bool should_trigger_wakeup, | 169 bool should_trigger_wakeup, |
172 const internal::TaskQueueImpl::Task* previous_task) { | 170 const internal::TaskQueueImpl::Task* previous_task) { |
173 DCHECK(main_thread_checker_.CalledOnValidThread()); | 171 DCHECK(main_thread_checker_.CalledOnValidThread()); |
174 TRACE_EVENT0(disabled_by_default_tracing_category_, | 172 TRACE_EVENT0(disabled_by_default_tracing_category_, |
175 "TaskQueueManager::UpdateWorkQueues"); | 173 "TaskQueueManager::UpdateWorkQueues"); |
176 internal::LazyNow lazy_now(this); | 174 internal::LazyNow lazy_now(tick_clock()); |
177 | 175 |
178 // Move any ready delayed tasks into the incomming queues. | 176 // Move any ready delayed tasks into the incomming queues. |
179 WakeupReadyDelayedQueues(&lazy_now); | 177 WakeupReadyDelayedQueues(&lazy_now); |
180 | 178 |
181 MoveNewlyUpdatableQueuesIntoUpdatableQueueSet(); | 179 MoveNewlyUpdatableQueuesIntoUpdatableQueueSet(); |
182 | 180 |
183 auto iter = updatable_queue_set_.begin(); | 181 auto iter = updatable_queue_set_.begin(); |
184 while (iter != updatable_queue_set_.end()) { | 182 while (iter != updatable_queue_set_.end()) { |
185 internal::TaskQueueImpl* queue = *iter++; | 183 internal::TaskQueueImpl* queue = *iter++; |
186 // NOTE Update work queue may erase itself from |updatable_queue_set_|. | 184 // NOTE Update work queue may erase itself from |updatable_queue_set_|. |
187 // This is fine, erasing an element won't invalidate any interator, as long | 185 // This is fine, erasing an element won't invalidate any interator, as long |
188 // as the iterator isn't the element being delated. | 186 // as the iterator isn't the element being delated. |
189 if (queue->work_queue().empty()) | 187 if (queue->work_queue().empty()) |
190 queue->UpdateWorkQueue(&lazy_now, should_trigger_wakeup, previous_task); | 188 queue->UpdateWorkQueue(&lazy_now, should_trigger_wakeup, previous_task); |
191 } | 189 } |
192 } | 190 } |
193 | 191 |
194 void TaskQueueManager::ScheduleDelayedWorkTask( | 192 void TaskQueueManager::ScheduleDelayedWorkTask( |
195 scoped_refptr<internal::TaskQueueImpl> queue, | 193 scoped_refptr<internal::TaskQueueImpl> queue, |
196 base::TimeTicks delayed_run_time) { | 194 base::TimeTicks delayed_run_time) { |
197 internal::LazyNow lazy_now(this); | 195 internal::LazyNow lazy_now(tick_clock()); |
198 ScheduleDelayedWork(queue.get(), delayed_run_time, &lazy_now); | 196 ScheduleDelayedWork(queue.get(), delayed_run_time, &lazy_now); |
199 } | 197 } |
200 | 198 |
201 void TaskQueueManager::ScheduleDelayedWork(internal::TaskQueueImpl* queue, | 199 void TaskQueueManager::ScheduleDelayedWork(internal::TaskQueueImpl* queue, |
202 base::TimeTicks delayed_run_time, | 200 base::TimeTicks delayed_run_time, |
203 internal::LazyNow* lazy_now) { | 201 internal::LazyNow* lazy_now) { |
204 if (!main_task_runner_->BelongsToCurrentThread()) { | 202 if (!delegate_->BelongsToCurrentThread()) { |
205 // NOTE posting a delayed task from a different thread is not expected to be | 203 // NOTE posting a delayed task from a different thread is not expected to be |
206 // common. This pathway is less optimal than perhaps it could be because | 204 // common. This pathway is less optimal than perhaps it could be because |
207 // it causes two main thread tasks to be run. Should this assumption prove | 205 // it causes two main thread tasks to be run. Should this assumption prove |
208 // to be false in future, we may need to revisit this. | 206 // to be false in future, we may need to revisit this. |
209 main_task_runner_->PostTask( | 207 delegate_->PostTask( |
210 FROM_HERE, base::Bind(&TaskQueueManager::ScheduleDelayedWorkTask, | 208 FROM_HERE, base::Bind(&TaskQueueManager::ScheduleDelayedWorkTask, |
211 weak_factory_.GetWeakPtr(), | 209 weak_factory_.GetWeakPtr(), |
212 scoped_refptr<internal::TaskQueueImpl>(queue), | 210 scoped_refptr<internal::TaskQueueImpl>(queue), |
213 delayed_run_time)); | 211 delayed_run_time)); |
214 return; | 212 return; |
215 } | 213 } |
216 | 214 |
217 // Make sure there's one (and only one) task posted to |main_task_runner_| | 215 // Make sure there's one (and only one) task posted to |delegate_| |
218 // to call |DelayedDoWork| at |delayed_run_time|. | 216 // to call |DelayedDoWork| at |delayed_run_time|. |
219 if (delayed_wakeup_multimap_.find(delayed_run_time) == | 217 if (delayed_wakeup_multimap_.find(delayed_run_time) == |
220 delayed_wakeup_multimap_.end()) { | 218 delayed_wakeup_multimap_.end()) { |
221 base::TimeDelta delay = | 219 base::TimeDelta delay = |
222 std::max(base::TimeDelta(), delayed_run_time - lazy_now->Now()); | 220 std::max(base::TimeDelta(), delayed_run_time - lazy_now->Now()); |
223 main_task_runner_->PostDelayedTask(FROM_HERE, do_work_closure_, delay); | 221 delegate_->PostDelayedTask(FROM_HERE, do_work_closure_, delay); |
224 } | 222 } |
225 delayed_wakeup_multimap_.insert(std::make_pair(delayed_run_time, queue)); | 223 delayed_wakeup_multimap_.insert(std::make_pair(delayed_run_time, queue)); |
226 } | 224 } |
227 | 225 |
228 void TaskQueueManager::WakeupReadyDelayedQueues(internal::LazyNow* lazy_now) { | 226 void TaskQueueManager::WakeupReadyDelayedQueues(internal::LazyNow* lazy_now) { |
229 // Wake up any queues with pending delayed work. Note std::multipmap stores | 227 // Wake up any queues with pending delayed work. Note std::multipmap stores |
230 // the elements sorted by key, so the begin() iterator points to the earliest | 228 // the elements sorted by key, so the begin() iterator points to the earliest |
231 // queue to wakeup. | 229 // queue to wakeup. |
232 std::set<internal::TaskQueueImpl*> dedup_set; | 230 std::set<internal::TaskQueueImpl*> dedup_set; |
233 while (!delayed_wakeup_multimap_.empty()) { | 231 while (!delayed_wakeup_multimap_.empty()) { |
234 DelayedWakeupMultimap::iterator next_wakeup = | 232 DelayedWakeupMultimap::iterator next_wakeup = |
235 delayed_wakeup_multimap_.begin(); | 233 delayed_wakeup_multimap_.begin(); |
236 if (next_wakeup->first > lazy_now->Now()) | 234 if (next_wakeup->first > lazy_now->Now()) |
237 break; | 235 break; |
238 // A queue could have any number of delayed tasks pending so it's worthwhile | 236 // A queue could have any number of delayed tasks pending so it's worthwhile |
239 // deduping calls to MoveReadyDelayedTasksToIncomingQueue since it takes a | 237 // deduping calls to MoveReadyDelayedTasksToIncomingQueue since it takes a |
240 // lock. NOTE the order in which these are called matters since the order | 238 // lock. NOTE the order in which these are called matters since the order |
241 // in which EnqueueTaskLocks is called is respected when choosing which | 239 // in which EnqueueTaskLocks is called is respected when choosing which |
242 // queue to execute a task from. | 240 // queue to execute a task from. |
243 if (dedup_set.insert(next_wakeup->second).second) | 241 if (dedup_set.insert(next_wakeup->second).second) |
244 next_wakeup->second->MoveReadyDelayedTasksToIncomingQueue(lazy_now); | 242 next_wakeup->second->MoveReadyDelayedTasksToIncomingQueue(lazy_now); |
245 delayed_wakeup_multimap_.erase(next_wakeup); | 243 delayed_wakeup_multimap_.erase(next_wakeup); |
246 } | 244 } |
247 } | 245 } |
248 | 246 |
249 void TaskQueueManager::MaybePostDoWorkOnMainRunner() { | 247 void TaskQueueManager::MaybePostDoWorkOnMainRunner() { |
250 bool on_main_thread = main_task_runner_->BelongsToCurrentThread(); | 248 bool on_main_thread = delegate_->BelongsToCurrentThread(); |
251 if (on_main_thread) { | 249 if (on_main_thread) { |
252 // We only want one pending DoWork posted from the main thread, or we risk | 250 // We only want one pending DoWork posted from the main thread, or we risk |
253 // an explosion of pending DoWorks which could starve out everything else. | 251 // an explosion of pending DoWorks which could starve out everything else. |
254 if (pending_dowork_count_ > 0) { | 252 if (pending_dowork_count_ > 0) { |
255 return; | 253 return; |
256 } | 254 } |
257 pending_dowork_count_++; | 255 pending_dowork_count_++; |
258 main_task_runner_->PostTask(FROM_HERE, | 256 delegate_->PostTask(FROM_HERE, decrement_pending_and_do_work_closure_); |
259 decrement_pending_and_do_work_closure_); | |
260 } else { | 257 } else { |
261 main_task_runner_->PostTask(FROM_HERE, do_work_closure_); | 258 delegate_->PostTask(FROM_HERE, do_work_closure_); |
262 } | 259 } |
263 } | 260 } |
264 | 261 |
265 void TaskQueueManager::DoWork(bool decrement_pending_dowork_count) { | 262 void TaskQueueManager::DoWork(bool decrement_pending_dowork_count) { |
266 if (decrement_pending_dowork_count) { | 263 if (decrement_pending_dowork_count) { |
267 pending_dowork_count_--; | 264 pending_dowork_count_--; |
268 DCHECK_GE(pending_dowork_count_, 0); | 265 DCHECK_GE(pending_dowork_count_, 0); |
269 } | 266 } |
270 DCHECK(main_thread_checker_.CalledOnValidThread()); | 267 DCHECK(main_thread_checker_.CalledOnValidThread()); |
271 | 268 |
272 if (!main_task_runner_->IsNested()) | 269 if (!delegate_->IsNested()) |
273 queues_to_delete_.clear(); | 270 queues_to_delete_.clear(); |
274 | 271 |
275 // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a | 272 // Pass false and nullptr to UpdateWorkQueues here to prevent waking up a |
276 // pump-after-wakeup queue. | 273 // pump-after-wakeup queue. |
277 UpdateWorkQueues(false, nullptr); | 274 UpdateWorkQueues(false, nullptr); |
278 | 275 |
279 internal::TaskQueueImpl::Task previous_task; | 276 internal::TaskQueueImpl::Task previous_task; |
280 for (int i = 0; i < work_batch_size_; i++) { | 277 for (int i = 0; i < work_batch_size_; i++) { |
281 internal::TaskQueueImpl* queue; | 278 internal::TaskQueueImpl* queue; |
282 if (!SelectQueueToService(&queue)) | 279 if (!SelectQueueToService(&queue)) |
283 break; | 280 break; |
284 | 281 |
285 switch (ProcessTaskFromWorkQueue(queue, &previous_task)) { | 282 switch (ProcessTaskFromWorkQueue(queue, &previous_task)) { |
286 case ProcessTaskResult::DEFERRED: | 283 case ProcessTaskResult::DEFERRED: |
287 // If a task was deferred, try again with another task. Note that this | 284 // If a task was deferred, try again with another task. Note that this |
288 // means deferred tasks (i.e. non-nestable tasks) will never trigger | 285 // means deferred tasks (i.e. non-nestable tasks) will never trigger |
289 // queue wake-ups. | 286 // queue wake-ups. |
290 continue; | 287 continue; |
291 case ProcessTaskResult::EXECUTED: | 288 case ProcessTaskResult::EXECUTED: |
292 break; | 289 break; |
293 case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED: | 290 case ProcessTaskResult::TASK_QUEUE_MANAGER_DELETED: |
294 return; // The TaskQueueManager got deleted, we must bail out. | 291 return; // The TaskQueueManager got deleted, we must bail out. |
295 } | 292 } |
296 bool should_trigger_wakeup = queue->wakeup_policy() == | 293 bool should_trigger_wakeup = queue->wakeup_policy() == |
297 TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES; | 294 TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES; |
298 UpdateWorkQueues(should_trigger_wakeup, &previous_task); | 295 UpdateWorkQueues(should_trigger_wakeup, &previous_task); |
299 | 296 |
300 // Only run a single task per batch in nested run loops so that we can | 297 // Only run a single task per batch in nested run loops so that we can |
301 // properly exit the nested loop when someone calls RunLoop::Quit(). | 298 // properly exit the nested loop when someone calls RunLoop::Quit(). |
302 if (main_task_runner_->IsNested()) | 299 if (delegate_->IsNested()) |
303 break; | 300 break; |
304 } | 301 } |
305 | 302 |
306 // TODO(alexclarke): Consider refactoring the above loop to terminate only | 303 // TODO(alexclarke): Consider refactoring the above loop to terminate only |
307 // when there's no more work left to be done, rather than posting a | 304 // when there's no more work left to be done, rather than posting a |
308 // continuation task. | 305 // continuation task. |
309 if (!selector_.EnabledWorkQueuesEmpty()) | 306 if (!selector_.EnabledWorkQueuesEmpty()) { |
310 MaybePostDoWorkOnMainRunner(); | 307 MaybePostDoWorkOnMainRunner(); |
| 308 } else { |
| 309 // Tell the task runner we have no more work. |
| 310 delegate_->OnNoMoreImmediateWork(); |
| 311 } |
311 } | 312 } |
312 | 313 |
313 bool TaskQueueManager::SelectQueueToService( | 314 bool TaskQueueManager::SelectQueueToService( |
314 internal::TaskQueueImpl** out_queue) { | 315 internal::TaskQueueImpl** out_queue) { |
315 bool should_run = selector_.SelectQueueToService(out_queue); | 316 bool should_run = selector_.SelectQueueToService(out_queue); |
316 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 317 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
317 disabled_by_default_tracing_category_, "TaskQueueManager", this, | 318 disabled_by_default_tracing_category_, "TaskQueueManager", this, |
318 AsValueWithSelectorResult(should_run, *out_queue)); | 319 AsValueWithSelectorResult(should_run, *out_queue)); |
319 return should_run; | 320 return should_run; |
320 } | 321 } |
321 | 322 |
322 void TaskQueueManager::DidQueueTask( | 323 void TaskQueueManager::DidQueueTask( |
323 const internal::TaskQueueImpl::Task& pending_task) { | 324 const internal::TaskQueueImpl::Task& pending_task) { |
324 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task); | 325 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task); |
325 } | 326 } |
326 | 327 |
327 TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue( | 328 TaskQueueManager::ProcessTaskResult TaskQueueManager::ProcessTaskFromWorkQueue( |
328 internal::TaskQueueImpl* queue, | 329 internal::TaskQueueImpl* queue, |
329 internal::TaskQueueImpl::Task* out_previous_task) { | 330 internal::TaskQueueImpl::Task* out_previous_task) { |
330 DCHECK(main_thread_checker_.CalledOnValidThread()); | 331 DCHECK(main_thread_checker_.CalledOnValidThread()); |
331 scoped_refptr<DeletionSentinel> protect(deletion_sentinel_); | 332 scoped_refptr<DeletionSentinel> protect(deletion_sentinel_); |
332 // TODO(alexclarke): consider std::move() when allowed. | 333 // TODO(alexclarke): consider std::move() when allowed. |
333 internal::TaskQueueImpl::Task pending_task = queue->TakeTaskFromWorkQueue(); | 334 internal::TaskQueueImpl::Task pending_task = queue->TakeTaskFromWorkQueue(); |
334 | 335 |
335 if (queue->GetQuiescenceMonitored()) | 336 if (queue->GetQuiescenceMonitored()) |
336 task_was_run_on_quiescence_monitored_queue_ = true; | 337 task_was_run_on_quiescence_monitored_queue_ = true; |
337 | 338 |
338 if (!pending_task.nestable && main_task_runner_->IsNested()) { | 339 if (!pending_task.nestable && delegate_->IsNested()) { |
339 // Defer non-nestable work to the main task runner. NOTE these tasks can be | 340 // Defer non-nestable work to the main task runner. NOTE these tasks can be |
340 // arbitrarily delayed so the additional delay should not be a problem. | 341 // arbitrarily delayed so the additional delay should not be a problem. |
341 // TODO(skyostil): Figure out a way to not forget which task queue the | 342 // TODO(skyostil): Figure out a way to not forget which task queue the |
342 // task is associated with. See http://crbug.com/522843. | 343 // task is associated with. See http://crbug.com/522843. |
343 main_task_runner_->PostNonNestableTask(pending_task.posted_from, | 344 delegate_->PostNonNestableTask(pending_task.posted_from, pending_task.task); |
344 pending_task.task); | |
345 return ProcessTaskResult::DEFERRED; | 345 return ProcessTaskResult::DEFERRED; |
346 } | 346 } |
347 | 347 |
348 TRACE_TASK_EXECUTION("TaskQueueManager::ProcessTaskFromWorkQueue", | 348 TRACE_TASK_EXECUTION("TaskQueueManager::ProcessTaskFromWorkQueue", |
349 pending_task); | 349 pending_task); |
350 if (queue->GetShouldNotifyObservers()) { | 350 if (queue->GetShouldNotifyObservers()) { |
351 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_, | 351 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, task_observers_, |
352 WillProcessTask(pending_task)); | 352 WillProcessTask(pending_task)); |
353 queue->NotifyWillProcessTask(pending_task); | 353 queue->NotifyWillProcessTask(pending_task); |
354 } | 354 } |
(...skipping 11 matching lines...) Expand all Loading... |
366 DidProcessTask(pending_task)); | 366 DidProcessTask(pending_task)); |
367 queue->NotifyDidProcessTask(pending_task); | 367 queue->NotifyDidProcessTask(pending_task); |
368 } | 368 } |
369 | 369 |
370 pending_task.task.Reset(); | 370 pending_task.task.Reset(); |
371 *out_previous_task = pending_task; | 371 *out_previous_task = pending_task; |
372 return ProcessTaskResult::EXECUTED; | 372 return ProcessTaskResult::EXECUTED; |
373 } | 373 } |
374 | 374 |
375 bool TaskQueueManager::RunsTasksOnCurrentThread() const { | 375 bool TaskQueueManager::RunsTasksOnCurrentThread() const { |
376 return main_task_runner_->RunsTasksOnCurrentThread(); | 376 return delegate_->RunsTasksOnCurrentThread(); |
377 } | |
378 | |
379 bool TaskQueueManager::PostDelayedTask( | |
380 const tracked_objects::Location& from_here, | |
381 const base::Closure& task, | |
382 base::TimeDelta delay) { | |
383 DCHECK_GE(delay, base::TimeDelta()); | |
384 return main_task_runner_->PostDelayedTask(from_here, task, delay); | |
385 } | 377 } |
386 | 378 |
387 void TaskQueueManager::SetWorkBatchSize(int work_batch_size) { | 379 void TaskQueueManager::SetWorkBatchSize(int work_batch_size) { |
388 DCHECK(main_thread_checker_.CalledOnValidThread()); | 380 DCHECK(main_thread_checker_.CalledOnValidThread()); |
389 DCHECK_GE(work_batch_size, 1); | 381 DCHECK_GE(work_batch_size, 1); |
390 work_batch_size_ = work_batch_size; | 382 work_batch_size_ = work_batch_size; |
391 } | 383 } |
392 | 384 |
393 void TaskQueueManager::AddTaskObserver( | 385 void TaskQueueManager::AddTaskObserver( |
394 base::MessageLoop::TaskObserver* task_observer) { | 386 base::MessageLoop::TaskObserver* task_observer) { |
395 DCHECK(main_thread_checker_.CalledOnValidThread()); | 387 DCHECK(main_thread_checker_.CalledOnValidThread()); |
396 task_observers_.AddObserver(task_observer); | 388 task_observers_.AddObserver(task_observer); |
397 } | 389 } |
398 | 390 |
399 void TaskQueueManager::RemoveTaskObserver( | 391 void TaskQueueManager::RemoveTaskObserver( |
400 base::MessageLoop::TaskObserver* task_observer) { | 392 base::MessageLoop::TaskObserver* task_observer) { |
401 DCHECK(main_thread_checker_.CalledOnValidThread()); | 393 DCHECK(main_thread_checker_.CalledOnValidThread()); |
402 task_observers_.RemoveObserver(task_observer); | 394 task_observers_.RemoveObserver(task_observer); |
403 } | 395 } |
404 | 396 |
405 void TaskQueueManager::SetTimeSourceForTesting( | |
406 scoped_ptr<base::TickClock> time_source) { | |
407 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
408 time_source_ = time_source.Pass(); | |
409 } | |
410 | |
411 bool TaskQueueManager::GetAndClearSystemIsQuiescentBit() { | 397 bool TaskQueueManager::GetAndClearSystemIsQuiescentBit() { |
412 bool task_was_run = task_was_run_on_quiescence_monitored_queue_; | 398 bool task_was_run = task_was_run_on_quiescence_monitored_queue_; |
413 task_was_run_on_quiescence_monitored_queue_ = false; | 399 task_was_run_on_quiescence_monitored_queue_ = false; |
414 return !task_was_run; | 400 return !task_was_run; |
415 } | 401 } |
416 | 402 |
417 base::TimeTicks TaskQueueManager::Now() const { | 403 base::TickClock* TaskQueueManager::tick_clock() const { |
418 return time_source_->NowTicks(); | 404 return delegate_.get(); |
419 } | 405 } |
420 | 406 |
421 int TaskQueueManager::GetNextSequenceNumber() { | 407 int TaskQueueManager::GetNextSequenceNumber() { |
422 return task_sequence_num_.GetNext(); | 408 return task_sequence_num_.GetNext(); |
423 } | 409 } |
424 | 410 |
425 scoped_refptr<base::trace_event::ConvertableToTraceFormat> | 411 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
426 TaskQueueManager::AsValueWithSelectorResult( | 412 TaskQueueManager::AsValueWithSelectorResult( |
427 bool should_run, | 413 bool should_run, |
428 internal::TaskQueueImpl* selected_queue) const { | 414 internal::TaskQueueImpl* selected_queue) const { |
(...skipping 18 matching lines...) Expand all Loading... |
447 } | 433 } |
448 | 434 |
449 void TaskQueueManager::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) { | 435 void TaskQueueManager::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) { |
450 DCHECK(main_thread_checker_.CalledOnValidThread()); | 436 DCHECK(main_thread_checker_.CalledOnValidThread()); |
451 // Only schedule DoWork if there's something to do. | 437 // Only schedule DoWork if there's something to do. |
452 if (!queue->work_queue().empty()) | 438 if (!queue->work_queue().empty()) |
453 MaybePostDoWorkOnMainRunner(); | 439 MaybePostDoWorkOnMainRunner(); |
454 } | 440 } |
455 | 441 |
456 } // namespace scheduler | 442 } // namespace scheduler |
OLD | NEW |