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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc

Issue 2726523002: Pass Callback to TaskRunner by value and consume it on invocation (1) (Closed)
Patch Set: erase Closure* Created 3 years, 8 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
OLDNEW
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 "platform/scheduler/base/task_queue_impl.h" 5 #include "platform/scheduler/base/task_queue_impl.h"
6 6
7 #include <utility>
8
7 #include "base/format_macros.h" 9 #include "base/format_macros.h"
8 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
9 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/time/time.h"
10 #include "base/trace_event/blame_context.h" 13 #include "base/trace_event/blame_context.h"
11 #include "platform/scheduler/base/task_queue_manager.h" 14 #include "platform/scheduler/base/task_queue_manager.h"
12 #include "platform/scheduler/base/task_queue_manager_delegate.h" 15 #include "platform/scheduler/base/task_queue_manager_delegate.h"
13 #include "platform/scheduler/base/time_domain.h" 16 #include "platform/scheduler/base/time_domain.h"
14 #include "platform/scheduler/base/work_queue.h" 17 #include "platform/scheduler/base/work_queue.h"
15 18
16 namespace blink { 19 namespace blink {
17 namespace scheduler { 20 namespace scheduler {
18 21
19 // static 22 // static
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 base::TimeTicks(), 112 base::TimeTicks(),
110 true), 113 true),
111 #ifndef NDEBUG 114 #ifndef NDEBUG
112 enqueue_order_set_(false), 115 enqueue_order_set_(false),
113 #endif 116 #endif
114 enqueue_order_(0) { 117 enqueue_order_(0) {
115 sequence_num = 0; 118 sequence_num = 0;
116 } 119 }
117 120
118 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, 121 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
119 const base::Closure& task, 122 base::Closure task,
120 base::TimeTicks desired_run_time, 123 base::TimeTicks desired_run_time,
121 EnqueueOrder sequence_number, 124 EnqueueOrder sequence_number,
122 bool nestable) 125 bool nestable)
123 : PendingTask(posted_from, task, desired_run_time, nestable), 126 : PendingTask(posted_from, std::move(task), desired_run_time, nestable),
124 #ifndef NDEBUG 127 #ifndef NDEBUG
125 enqueue_order_set_(false), 128 enqueue_order_set_(false),
126 #endif 129 #endif
127 enqueue_order_(0) { 130 enqueue_order_(0) {
128 sequence_num = sequence_number; 131 sequence_num = sequence_number;
129 } 132 }
130 133
131 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, 134 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
132 const base::Closure& task, 135 base::Closure task,
133 base::TimeTicks desired_run_time, 136 base::TimeTicks desired_run_time,
134 EnqueueOrder sequence_number, 137 EnqueueOrder sequence_number,
135 bool nestable, 138 bool nestable,
136 EnqueueOrder enqueue_order) 139 EnqueueOrder enqueue_order)
137 : PendingTask(posted_from, task, desired_run_time, nestable), 140 : PendingTask(posted_from, std::move(task), desired_run_time, nestable),
138 #ifndef NDEBUG 141 #ifndef NDEBUG
139 enqueue_order_set_(true), 142 enqueue_order_set_(true),
140 #endif 143 #endif
141 enqueue_order_(enqueue_order) { 144 enqueue_order_(enqueue_order) {
142 sequence_num = sequence_number; 145 sequence_num = sequence_number;
143 } 146 }
144 147
145 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, 148 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager,
146 TimeDomain* time_domain) 149 TimeDomain* time_domain)
147 : task_queue_manager(task_queue_manager), time_domain(time_domain) {} 150 : task_queue_manager(task_queue_manager), time_domain(time_domain) {}
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 any_thread().immediate_incoming_queue.clear(); 186 any_thread().immediate_incoming_queue.clear();
184 main_thread_only().immediate_work_queue.reset(); 187 main_thread_only().immediate_work_queue.reset();
185 main_thread_only().delayed_work_queue.reset(); 188 main_thread_only().delayed_work_queue.reset();
186 } 189 }
187 190
188 bool TaskQueueImpl::RunsTasksOnCurrentThread() const { 191 bool TaskQueueImpl::RunsTasksOnCurrentThread() const {
189 return base::PlatformThread::CurrentId() == thread_id_; 192 return base::PlatformThread::CurrentId() == thread_id_;
190 } 193 }
191 194
192 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here, 195 bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here,
193 const base::Closure& task, 196 base::Closure task,
194 base::TimeDelta delay) { 197 base::TimeDelta delay) {
195 if (delay.is_zero()) 198 if (delay.is_zero())
196 return PostImmediateTaskImpl(from_here, task, TaskType::NORMAL); 199 return PostImmediateTaskImpl(from_here, std::move(task), TaskType::NORMAL);
197 200
198 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL); 201 return PostDelayedTaskImpl(from_here, std::move(task), delay,
202 TaskType::NORMAL);
199 } 203 }
200 204
201 bool TaskQueueImpl::PostNonNestableDelayedTask( 205 bool TaskQueueImpl::PostNonNestableDelayedTask(
202 const tracked_objects::Location& from_here, 206 const tracked_objects::Location& from_here,
203 const base::Closure& task, 207 base::Closure task,
204 base::TimeDelta delay) { 208 base::TimeDelta delay) {
205 if (delay.is_zero()) 209 if (delay.is_zero())
206 return PostImmediateTaskImpl(from_here, task, TaskType::NON_NESTABLE); 210 return PostImmediateTaskImpl(from_here, std::move(task),
211 TaskType::NON_NESTABLE);
207 212
208 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); 213 return PostDelayedTaskImpl(from_here, std::move(task), delay,
214 TaskType::NON_NESTABLE);
209 } 215 }
210 216
211 bool TaskQueueImpl::PostImmediateTaskImpl( 217 bool TaskQueueImpl::PostImmediateTaskImpl(
212 const tracked_objects::Location& from_here, 218 const tracked_objects::Location& from_here,
213 const base::Closure& task, 219 base::Closure task,
214 TaskType task_type) { 220 TaskType task_type) {
215 base::AutoLock lock(any_thread_lock_); 221 base::AutoLock lock(any_thread_lock_);
216 if (!any_thread().task_queue_manager) 222 if (!any_thread().task_queue_manager)
217 return false; 223 return false;
218 224
219 EnqueueOrder sequence_number = 225 EnqueueOrder sequence_number =
220 any_thread().task_queue_manager->GetNextSequenceNumber(); 226 any_thread().task_queue_manager->GetNextSequenceNumber();
221 227
222 PushOntoImmediateIncomingQueueLocked( 228 PushOntoImmediateIncomingQueueLocked(from_here, std::move(task),
223 from_here, 229 base::TimeTicks(), sequence_number,
224 task, 230 task_type != TaskType::NON_NESTABLE);
225 base::TimeTicks(),
226 sequence_number,
227 task_type != TaskType::NON_NESTABLE);
228 return true; 231 return true;
229 } 232 }
230 233
231 bool TaskQueueImpl::PostDelayedTaskImpl( 234 bool TaskQueueImpl::PostDelayedTaskImpl(
232 const tracked_objects::Location& from_here, 235 const tracked_objects::Location& from_here,
233 const base::Closure& task, 236 base::Closure task,
234 base::TimeDelta delay, 237 base::TimeDelta delay,
235 TaskType task_type) { 238 TaskType task_type) {
236 DCHECK_GT(delay, base::TimeDelta()); 239 DCHECK_GT(delay, base::TimeDelta());
237 if (base::PlatformThread::CurrentId() == thread_id_) { 240 if (base::PlatformThread::CurrentId() == thread_id_) {
238 // Lock-free fast path for delayed tasks posted from the main thread. 241 // Lock-free fast path for delayed tasks posted from the main thread.
239 if (!main_thread_only().task_queue_manager) 242 if (!main_thread_only().task_queue_manager)
240 return false; 243 return false;
241 244
242 EnqueueOrder sequence_number = 245 EnqueueOrder sequence_number =
243 main_thread_only().task_queue_manager->GetNextSequenceNumber(); 246 main_thread_only().task_queue_manager->GetNextSequenceNumber();
244 247
245 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); 248 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now();
246 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; 249 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
247 PushOntoDelayedIncomingQueueFromMainThread( 250 PushOntoDelayedIncomingQueueFromMainThread(
248 Task(from_here, task, time_domain_delayed_run_time, sequence_number, 251 Task(from_here, std::move(task), time_domain_delayed_run_time,
249 task_type != TaskType::NON_NESTABLE), 252 sequence_number, task_type != TaskType::NON_NESTABLE),
250 time_domain_now); 253 time_domain_now);
251 } else { 254 } else {
252 // NOTE posting a delayed task from a different thread is not expected to 255 // NOTE posting a delayed task from a different thread is not expected to
253 // be common. This pathway is less optimal than perhaps it could be 256 // be common. This pathway is less optimal than perhaps it could be
254 // because it causes two main thread tasks to be run. Should this 257 // because it causes two main thread tasks to be run. Should this
255 // assumption prove to be false in future, we may need to revisit this. 258 // assumption prove to be false in future, we may need to revisit this.
256 base::AutoLock lock(any_thread_lock_); 259 base::AutoLock lock(any_thread_lock_);
257 if (!any_thread().task_queue_manager) 260 if (!any_thread().task_queue_manager)
258 return false; 261 return false;
259 262
260 EnqueueOrder sequence_number = 263 EnqueueOrder sequence_number =
261 any_thread().task_queue_manager->GetNextSequenceNumber(); 264 any_thread().task_queue_manager->GetNextSequenceNumber();
262 265
263 base::TimeTicks time_domain_now = any_thread().time_domain->Now(); 266 base::TimeTicks time_domain_now = any_thread().time_domain->Now();
264 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; 267 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
265 PushOntoDelayedIncomingQueueLocked( 268 PushOntoDelayedIncomingQueueLocked(
266 Task(from_here, task, time_domain_delayed_run_time, sequence_number, 269 Task(from_here, std::move(task), time_domain_delayed_run_time,
267 task_type != TaskType::NON_NESTABLE)); 270 sequence_number, task_type != TaskType::NON_NESTABLE));
268 } 271 }
269 return true; 272 return true;
270 } 273 }
271 274
272 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( 275 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread(
273 Task pending_task, base::TimeTicks now) { 276 Task pending_task, base::TimeTicks now) {
274 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; 277 base::TimeTicks delayed_run_time = pending_task.delayed_run_time;
275 main_thread_only().task_queue_manager->DidQueueTask(pending_task); 278 main_thread_only().task_queue_manager->DidQueueTask(pending_task);
276 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); 279 main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
277 280
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 } else { 322 } else {
320 // If |delayed_run_time| is in the future we can queue it as normal. 323 // If |delayed_run_time| is in the future we can queue it as normal.
321 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task), 324 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task),
322 time_domain_now); 325 time_domain_now);
323 } 326 }
324 TraceQueueSize(false); 327 TraceQueueSize(false);
325 } 328 }
326 329
327 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( 330 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
328 const tracked_objects::Location& posted_from, 331 const tracked_objects::Location& posted_from,
329 const base::Closure& task, 332 base::Closure task,
330 base::TimeTicks desired_run_time, 333 base::TimeTicks desired_run_time,
331 EnqueueOrder sequence_number, 334 EnqueueOrder sequence_number,
332 bool nestable) { 335 bool nestable) {
333 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make 336 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
334 // it run. 337 // it run.
335 if (any_thread().immediate_incoming_queue.empty()) { 338 if (any_thread().immediate_incoming_queue.empty()) {
336 // However there's no point posting a DoWork for a blocked queue. NB we can 339 // However there's no point posting a DoWork for a blocked queue. NB we can
337 // only tell if it's disabled from the main thread. 340 // only tell if it's disabled from the main thread.
338 bool queue_is_blocked = 341 bool queue_is_blocked =
339 RunsTasksOnCurrentThread() && 342 RunsTasksOnCurrentThread() &&
340 (!IsQueueEnabled() || main_thread_only().current_fence); 343 (!IsQueueEnabled() || main_thread_only().current_fence);
341 any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork( 344 any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork(
342 this, sequence_number, queue_is_blocked); 345 this, sequence_number, queue_is_blocked);
343 any_thread().time_domain->OnQueueHasImmediateWork(this); 346 any_thread().time_domain->OnQueueHasImmediateWork(this);
344 } 347 }
345 any_thread().immediate_incoming_queue.emplace_back( 348 any_thread().immediate_incoming_queue.emplace_back(
346 posted_from, task, desired_run_time, sequence_number, nestable, 349 posted_from, std::move(task), desired_run_time, sequence_number, nestable,
347 sequence_number); 350 sequence_number);
348 any_thread().task_queue_manager->DidQueueTask( 351 any_thread().task_queue_manager->DidQueueTask(
349 any_thread().immediate_incoming_queue.back()); 352 any_thread().immediate_incoming_queue.back());
350 TraceQueueSize(true); 353 TraceQueueSize(true);
351 } 354 }
352 355
353 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { 356 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() {
354 if (!main_thread_only().immediate_work_queue->Empty()) 357 if (!main_thread_only().immediate_work_queue->Empty())
355 return; 358 return;
356 359
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 882
880 void TaskQueueImpl::PushImmediateIncomingTaskForTest( 883 void TaskQueueImpl::PushImmediateIncomingTaskForTest(
881 TaskQueueImpl::Task&& task) { 884 TaskQueueImpl::Task&& task) {
882 base::AutoLock lock(any_thread_lock_); 885 base::AutoLock lock(any_thread_lock_);
883 any_thread().immediate_incoming_queue.push_back(std::move(task)); 886 any_thread().immediate_incoming_queue.push_back(std::move(task));
884 } 887 }
885 888
886 } // namespace internal 889 } // namespace internal
887 } // namespace scheduler 890 } // namespace scheduler
888 } // namespace blink 891 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698