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/task_queue_manager.h" | 7 #include "components/scheduler/base/task_queue_manager.h" |
8 #include "components/scheduler/base/task_queue_manager_delegate.h" | 8 #include "components/scheduler/base/task_queue_manager_delegate.h" |
9 #include "components/scheduler/base/time_domain.h" | 9 #include "components/scheduler/base/time_domain.h" |
10 | 10 |
11 namespace scheduler { | 11 namespace scheduler { |
12 namespace internal { | 12 namespace internal { |
13 | 13 |
14 TaskQueueImpl::TaskQueueImpl( | 14 TaskQueueImpl::TaskQueueImpl( |
15 TaskQueueManager* task_queue_manager, | 15 TaskQueueManager* task_queue_manager, |
16 const scoped_refptr<TimeDomain>& time_domain, | 16 TimeDomain* time_domain, |
17 const Spec& spec, | 17 const Spec& spec, |
18 const char* disabled_by_default_tracing_category, | 18 const char* disabled_by_default_tracing_category, |
19 const char* disabled_by_default_verbose_tracing_category) | 19 const char* disabled_by_default_verbose_tracing_category) |
20 : thread_id_(base::PlatformThread::CurrentId()), | 20 : thread_id_(base::PlatformThread::CurrentId()), |
21 any_thread_(task_queue_manager, spec.pump_policy, time_domain), | 21 any_thread_(task_queue_manager, spec.pump_policy, time_domain), |
22 name_(spec.name), | 22 name_(spec.name), |
23 disabled_by_default_tracing_category_( | 23 disabled_by_default_tracing_category_( |
24 disabled_by_default_tracing_category), | 24 disabled_by_default_tracing_category), |
25 disabled_by_default_verbose_tracing_category_( | 25 disabled_by_default_verbose_tracing_category_( |
26 disabled_by_default_verbose_tracing_category), | 26 disabled_by_default_verbose_tracing_category), |
27 main_thread_only_(task_queue_manager), | 27 main_thread_only_(task_queue_manager), |
28 wakeup_policy_(spec.wakeup_policy), | 28 wakeup_policy_(spec.wakeup_policy), |
29 should_monitor_quiescence_(spec.should_monitor_quiescence), | 29 should_monitor_quiescence_(spec.should_monitor_quiescence), |
30 should_notify_observers_(spec.should_notify_observers) { | 30 should_notify_observers_(spec.should_notify_observers) { |
31 DCHECK(time_domain.get()); | 31 DCHECK(time_domain); |
32 time_domain->RegisterQueue(this); | |
32 } | 33 } |
33 | 34 |
34 TaskQueueImpl::~TaskQueueImpl() {} | 35 TaskQueueImpl::~TaskQueueImpl() {} |
Sami
2015/11/26 19:27:50
nit: DCHECK that we no longer have a time domain?
alex clarke (OOO till 29th)
2015/11/27 10:01:59
I added a de-register here too. It was needed in
| |
35 | 36 |
36 TaskQueueImpl::Task::Task() | 37 TaskQueueImpl::Task::Task() |
37 : PendingTask(tracked_objects::Location(), | 38 : PendingTask(tracked_objects::Location(), |
38 base::Closure(), | 39 base::Closure(), |
39 base::TimeTicks(), | 40 base::TimeTicks(), |
40 true), | 41 true), |
41 #ifndef NDEBUG | 42 #ifndef NDEBUG |
42 enqueue_order_set_(false), | 43 enqueue_order_set_(false), |
43 #endif | 44 #endif |
44 enqueue_order_(0) { | 45 enqueue_order_(0) { |
45 sequence_num = 0; | 46 sequence_num = 0; |
46 } | 47 } |
47 | 48 |
48 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, | 49 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, |
49 const base::Closure& task, | 50 const base::Closure& task, |
50 int sequence_number, | 51 int sequence_number, |
51 bool nestable) | 52 bool nestable) |
52 : PendingTask(posted_from, task, base::TimeTicks(), nestable), | 53 : PendingTask(posted_from, task, base::TimeTicks(), nestable), |
53 #ifndef NDEBUG | 54 #ifndef NDEBUG |
54 enqueue_order_set_(false), | 55 enqueue_order_set_(false), |
55 #endif | 56 #endif |
56 enqueue_order_(0) { | 57 enqueue_order_(0) { |
57 sequence_num = sequence_number; | 58 sequence_num = sequence_number; |
58 } | 59 } |
59 | 60 |
60 TaskQueueImpl::AnyThread::AnyThread( | 61 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, |
61 TaskQueueManager* task_queue_manager, | 62 PumpPolicy pump_policy, |
62 PumpPolicy pump_policy, | 63 TimeDomain* time_domain) |
63 const scoped_refptr<TimeDomain>& time_domain) | |
64 : task_queue_manager(task_queue_manager), | 64 : task_queue_manager(task_queue_manager), |
65 pump_policy(pump_policy), | 65 pump_policy(pump_policy), |
66 time_domain(time_domain) {} | 66 time_domain(time_domain) {} |
67 | 67 |
68 TaskQueueImpl::AnyThread::~AnyThread() {} | 68 TaskQueueImpl::AnyThread::~AnyThread() {} |
69 | 69 |
70 TaskQueueImpl::MainThreadOnly::MainThreadOnly( | 70 TaskQueueImpl::MainThreadOnly::MainThreadOnly( |
71 TaskQueueManager* task_queue_manager) | 71 TaskQueueManager* task_queue_manager) |
72 : task_queue_manager(task_queue_manager), | 72 : task_queue_manager(task_queue_manager), |
73 set_index(0) {} | 73 set_index(0) {} |
74 | 74 |
75 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} | 75 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} |
76 | 76 |
77 void TaskQueueImpl::UnregisterTaskQueue() { | 77 void TaskQueueImpl::UnregisterTaskQueue() { |
78 base::AutoLock lock(any_thread_lock_); | 78 base::AutoLock lock(any_thread_lock_); |
79 if (!any_thread().task_queue_manager) | 79 if (!any_thread().task_queue_manager) |
80 return; | 80 return; |
81 any_thread().time_domain->UnregisterQueue(this); | 81 if (any_thread().time_domain) |
82 any_thread().time_domain->UnregisterQueue(this); | |
82 any_thread().time_domain = nullptr; | 83 any_thread().time_domain = nullptr; |
83 any_thread().task_queue_manager->UnregisterTaskQueue(this); | 84 any_thread().task_queue_manager->UnregisterTaskQueue(this); |
84 | 85 |
85 any_thread().task_queue_manager = nullptr; | 86 any_thread().task_queue_manager = nullptr; |
86 main_thread_only().task_queue_manager = nullptr; | 87 main_thread_only().task_queue_manager = nullptr; |
87 any_thread().delayed_task_queue = std::priority_queue<Task>(); | 88 any_thread().delayed_task_queue = std::priority_queue<Task>(); |
88 any_thread().incoming_queue = std::queue<Task>(); | 89 any_thread().incoming_queue = std::queue<Task>(); |
89 main_thread_only().work_queue = std::queue<Task>(); | 90 main_thread_only().work_queue = std::queue<Task>(); |
90 } | 91 } |
91 | 92 |
92 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { | 93 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { |
93 base::AutoLock lock(any_thread_lock_); | 94 base::AutoLock lock(any_thread_lock_); |
94 return base::PlatformThread::CurrentId() == thread_id_; | 95 return base::PlatformThread::CurrentId() == thread_id_; |
95 } | 96 } |
96 | 97 |
97 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, | 98 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, |
98 const base::Closure& task, | 99 const base::Closure& task, |
99 base::TimeDelta delay) { | 100 base::TimeDelta delay) { |
100 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL); | 101 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL); |
101 } | 102 } |
102 | 103 |
103 bool TaskQueueImpl::PostNonNestableDelayedTask( | 104 bool TaskQueueImpl::PostNonNestableDelayedTask( |
104 const tracked_objects::Location& from_here, | 105 const tracked_objects::Location& from_here, |
105 const base::Closure& task, | 106 const base::Closure& task, |
106 base::TimeDelta delay) { | 107 base::TimeDelta delay) { |
107 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); | 108 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); |
108 } | 109 } |
109 | 110 |
110 bool TaskQueueImpl::PostDelayedTaskAt( | |
111 const tracked_objects::Location& from_here, | |
112 const base::Closure& task, | |
113 base::TimeTicks desired_run_time) { | |
114 base::AutoLock lock(any_thread_lock_); | |
115 if (!any_thread().task_queue_manager) | |
116 return false; | |
117 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); | |
118 return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, | |
119 TaskType::NORMAL); | |
120 } | |
121 | |
122 bool TaskQueueImpl::PostDelayedTaskImpl( | 111 bool TaskQueueImpl::PostDelayedTaskImpl( |
123 const tracked_objects::Location& from_here, | 112 const tracked_objects::Location& from_here, |
124 const base::Closure& task, | 113 const base::Closure& task, |
125 base::TimeDelta delay, | 114 base::TimeDelta delay, |
126 TaskType task_type) { | 115 TaskType task_type) { |
127 base::AutoLock lock(any_thread_lock_); | 116 base::AutoLock lock(any_thread_lock_); |
128 if (!any_thread().task_queue_manager) | 117 if (!any_thread().task_queue_manager) |
129 return false; | 118 return false; |
130 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); | 119 LazyNow lazy_now(any_thread().time_domain->CreateLazyNow()); |
131 base::TimeTicks desired_run_time; | 120 base::TimeTicks desired_run_time; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 any_thread().task_queue_manager->DidQueueTask(thread_hop_task); | 158 any_thread().task_queue_manager->DidQueueTask(thread_hop_task); |
170 EnqueueTaskLocked(thread_hop_task); | 159 EnqueueTaskLocked(thread_hop_task); |
171 } | 160 } |
172 return true; | 161 return true; |
173 } | 162 } |
174 pending_task.set_enqueue_order(pending_task.sequence_num); | 163 pending_task.set_enqueue_order(pending_task.sequence_num); |
175 EnqueueTaskLocked(pending_task); | 164 EnqueueTaskLocked(pending_task); |
176 return true; | 165 return true; |
177 } | 166 } |
178 | 167 |
179 void TaskQueueImpl::ScheduleDelayedWorkTask( | 168 void TaskQueueImpl::ScheduleDelayedWorkTask(TimeDomain* time_domain, |
180 const scoped_refptr<TimeDomain> time_domain, | 169 base::TimeTicks desired_run_time) { |
181 base::TimeTicks desired_run_time) { | |
182 DCHECK(main_thread_checker_.CalledOnValidThread()); | 170 DCHECK(main_thread_checker_.CalledOnValidThread()); |
183 LazyNow lazy_now(time_domain->CreateLazyNow()); | 171 LazyNow lazy_now(time_domain->CreateLazyNow()); |
184 time_domain->ScheduleDelayedWork(this, desired_run_time, &lazy_now); | 172 time_domain->ScheduleDelayedWork(this, desired_run_time, &lazy_now); |
185 } | 173 } |
186 | 174 |
187 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) { | 175 void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue(LazyNow* lazy_now) { |
188 base::AutoLock lock(any_thread_lock_); | 176 base::AutoLock lock(any_thread_lock_); |
189 if (!any_thread().task_queue_manager) | 177 if (!any_thread().task_queue_manager) |
190 return; | 178 return; |
191 | 179 |
(...skipping 20 matching lines...) Expand all Loading... | |
212 return main_thread_only().task_queue_manager->selector_.IsQueueEnabled(this); | 200 return main_thread_only().task_queue_manager->selector_.IsQueueEnabled(this); |
213 } | 201 } |
214 | 202 |
215 TaskQueue::QueueState TaskQueueImpl::GetQueueState() const { | 203 TaskQueue::QueueState TaskQueueImpl::GetQueueState() const { |
216 if (!main_thread_only().work_queue.empty()) | 204 if (!main_thread_only().work_queue.empty()) |
217 return QueueState::HAS_WORK; | 205 return QueueState::HAS_WORK; |
218 | 206 |
219 { | 207 { |
220 base::AutoLock lock(any_thread_lock_); | 208 base::AutoLock lock(any_thread_lock_); |
221 if (any_thread().incoming_queue.empty()) { | 209 if (any_thread().incoming_queue.empty()) { |
222 return QueueState::EMPTY; | 210 if (any_thread().delayed_task_queue.empty()) |
211 return QueueState::EMPTY; | |
212 else | |
213 return QueueState::NO_IMMEDIATE_WORK; | |
223 } else { | 214 } else { |
224 return QueueState::NEEDS_PUMPING; | 215 return QueueState::NEEDS_PUMPING; |
225 } | 216 } |
226 } | 217 } |
227 } | 218 } |
228 | |
Sami
2015/11/26 19:27:50
Intentional?
alex clarke (OOO till 29th)
2015/11/27 10:01:59
Done.
| |
229 bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const Task* task) { | 219 bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const Task* task) { |
230 // A null task is passed when UpdateQueue is called before any task is run. | 220 // A null task is passed when UpdateQueue is called before any task is run. |
231 // In this case we don't want to pump an after_wakeup queue, so return true | 221 // In this case we don't want to pump an after_wakeup queue, so return true |
232 // here. | 222 // here. |
233 if (!task) | 223 if (!task) |
234 return true; | 224 return true; |
235 | 225 |
236 // Return false if there are no task in the incoming queue. | 226 // Return false if there are no task in the incoming queue. |
237 if (any_thread().incoming_queue.empty()) | 227 if (any_thread().incoming_queue.empty()) |
238 return false; | 228 return false; |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 } | 488 } |
499 | 489 |
500 void TaskQueueImpl::NotifyDidProcessTask( | 490 void TaskQueueImpl::NotifyDidProcessTask( |
501 const base::PendingTask& pending_task) { | 491 const base::PendingTask& pending_task) { |
502 DCHECK(should_notify_observers_); | 492 DCHECK(should_notify_observers_); |
503 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, | 493 FOR_EACH_OBSERVER(base::MessageLoop::TaskObserver, |
504 main_thread_only().task_observers, | 494 main_thread_only().task_observers, |
505 DidProcessTask(pending_task)); | 495 DidProcessTask(pending_task)); |
506 } | 496 } |
507 | 497 |
508 void TaskQueueImpl::SetTimeDomain( | 498 void TaskQueueImpl::SetTimeDomain(TimeDomain* time_domain) { |
509 const scoped_refptr<TimeDomain>& time_domain) { | |
510 base::AutoLock lock(any_thread_lock_); | 499 base::AutoLock lock(any_thread_lock_); |
511 DCHECK(main_thread_checker_.CalledOnValidThread()); | 500 DCHECK(main_thread_checker_.CalledOnValidThread()); |
512 if (time_domain == any_thread().time_domain) | 501 if (time_domain == any_thread().time_domain) |
513 return; | 502 return; |
514 | 503 |
515 any_thread().time_domain->MigrateQueue(this, time_domain.get()); | 504 if (time_domain) |
505 any_thread().time_domain->MigrateQueue(this, time_domain); | |
516 any_thread().time_domain = time_domain; | 506 any_thread().time_domain = time_domain; |
517 } | 507 } |
518 | 508 |
519 // static | 509 // static |
520 void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue, | 510 void TaskQueueImpl::QueueAsValueInto(const std::queue<Task>& queue, |
521 base::trace_event::TracedValue* state) { | 511 base::trace_event::TracedValue* state) { |
522 std::queue<Task> queue_copy(queue); | 512 std::queue<Task> queue_copy(queue); |
523 while (!queue_copy.empty()) { | 513 while (!queue_copy.empty()) { |
524 TaskAsValueInto(queue_copy.front(), state); | 514 TaskAsValueInto(queue_copy.front(), state); |
525 queue_copy.pop(); | 515 queue_copy.pop(); |
(...skipping 25 matching lines...) Expand all Loading... | |
551 state->EndDictionary(); | 541 state->EndDictionary(); |
552 } | 542 } |
553 | 543 |
554 size_t TaskQueueImpl::IncomingQueueSizeForTest() const { | 544 size_t TaskQueueImpl::IncomingQueueSizeForTest() const { |
555 base::AutoLock lock(any_thread_lock_); | 545 base::AutoLock lock(any_thread_lock_); |
556 return any_thread().incoming_queue.size(); | 546 return any_thread().incoming_queue.size(); |
557 } | 547 } |
558 | 548 |
559 } // namespace internal | 549 } // namespace internal |
560 } // namespace scheduler | 550 } // namespace scheduler |
OLD | NEW |