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

Side by Side Diff: components/scheduler/base/task_queue_impl.cc

Issue 2158993002: (Merge) Fix a bug that could occasionaly cause setInterval to stop (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2785
Patch Set: Created 4 years, 5 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 "components/scheduler/base/task_queue_impl.h" 5 #include "components/scheduler/base/task_queue_impl.h"
6 6
7 #include "base/trace_event/blame_context.h" 7 #include "base/trace_event/blame_context.h"
8 #include "components/scheduler/base/task_queue_manager.h" 8 #include "components/scheduler/base/task_queue_manager.h"
9 #include "components/scheduler/base/task_queue_manager_delegate.h" 9 #include "components/scheduler/base/task_queue_manager_delegate.h"
10 #include "components/scheduler/base/time_domain.h" 10 #include "components/scheduler/base/time_domain.h"
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 DCHECK_GT(delay, base::TimeDelta()); 182 DCHECK_GT(delay, base::TimeDelta());
183 if (base::PlatformThread::CurrentId() == thread_id_) { 183 if (base::PlatformThread::CurrentId() == thread_id_) {
184 // Lock-free fast path for delayed tasks posted from the main thread. 184 // Lock-free fast path for delayed tasks posted from the main thread.
185 if (!main_thread_only().task_queue_manager) 185 if (!main_thread_only().task_queue_manager)
186 return false; 186 return false;
187 187
188 EnqueueOrder sequence_number = 188 EnqueueOrder sequence_number =
189 main_thread_only().task_queue_manager->GetNextSequenceNumber(); 189 main_thread_only().task_queue_manager->GetNextSequenceNumber();
190 190
191 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); 191 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now();
192 base::TimeTicks time_domain_delayed_run_time = 192 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
193 main_thread_only().time_domain->ComputeDelayedRunTime(time_domain_now,
194 delay);
195 PushOntoDelayedIncomingQueueFromMainThread( 193 PushOntoDelayedIncomingQueueFromMainThread(
196 Task(from_here, task, time_domain_delayed_run_time, sequence_number, 194 Task(from_here, task, time_domain_delayed_run_time, sequence_number,
197 task_type != TaskType::NON_NESTABLE), 195 task_type != TaskType::NON_NESTABLE),
198 time_domain_now); 196 time_domain_now);
199 } else { 197 } else {
200 // NOTE posting a delayed task from a different thread is not expected to 198 // NOTE posting a delayed task from a different thread is not expected to
201 // be common. This pathway is less optimal than perhaps it could be 199 // be common. This pathway is less optimal than perhaps it could be
202 // because it causes two main thread tasks to be run. Should this 200 // because it causes two main thread tasks to be run. Should this
203 // assumption prove to be false in future, we may need to revisit this. 201 // assumption prove to be false in future, we may need to revisit this.
204 base::AutoLock lock(any_thread_lock_); 202 base::AutoLock lock(any_thread_lock_);
205 if (!any_thread().task_queue_manager) 203 if (!any_thread().task_queue_manager)
206 return false; 204 return false;
207 205
208 EnqueueOrder sequence_number = 206 EnqueueOrder sequence_number =
209 any_thread().task_queue_manager->GetNextSequenceNumber(); 207 any_thread().task_queue_manager->GetNextSequenceNumber();
210 208
211 base::TimeTicks time_domain_now = any_thread().time_domain->Now(); 209 base::TimeTicks time_domain_now = any_thread().time_domain->Now();
212 base::TimeTicks time_domain_delayed_run_time = 210 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
213 any_thread().time_domain->ComputeDelayedRunTime(time_domain_now, delay);
214 PushOntoDelayedIncomingQueueLocked( 211 PushOntoDelayedIncomingQueueLocked(
215 Task(from_here, task, time_domain_delayed_run_time, sequence_number, 212 Task(from_here, task, time_domain_delayed_run_time, sequence_number,
216 task_type != TaskType::NON_NESTABLE)); 213 task_type != TaskType::NON_NESTABLE));
217 } 214 }
218 return true; 215 return true;
219 } 216 }
220 217
221 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( 218 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread(
222 const Task& pending_task, 219 const Task& pending_task,
223 base::TimeTicks now) { 220 base::TimeTicks now) {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 main_thread_only().delayed_work_queue->Size() + 439 main_thread_only().delayed_work_queue->Size() +
443 main_thread_only().delayed_incoming_queue.size()); 440 main_thread_only().delayed_incoming_queue.size());
444 if (!is_locked) 441 if (!is_locked)
445 any_thread_lock_.Release(); 442 any_thread_lock_.Release();
446 } 443 }
447 444
448 void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) { 445 void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) {
449 base::AutoLock lock(any_thread_lock_); 446 base::AutoLock lock(any_thread_lock_);
450 if (pump_policy == PumpPolicy::AUTO && 447 if (pump_policy == PumpPolicy::AUTO &&
451 any_thread().pump_policy != PumpPolicy::AUTO) { 448 any_thread().pump_policy != PumpPolicy::AUTO) {
452 PumpQueueLocked(true); 449 LazyNow lazy_now(main_thread_only().time_domain->CreateLazyNow());
450 PumpQueueLocked(&lazy_now, true);
453 } 451 }
454 any_thread().pump_policy = pump_policy; 452 any_thread().pump_policy = pump_policy;
455 main_thread_only().pump_policy = pump_policy; 453 main_thread_only().pump_policy = pump_policy;
456 } 454 }
457 455
458 TaskQueue::PumpPolicy TaskQueueImpl::GetPumpPolicy() const { 456 TaskQueue::PumpPolicy TaskQueueImpl::GetPumpPolicy() const {
459 return main_thread_only().pump_policy; 457 return main_thread_only().pump_policy;
460 } 458 }
461 459
462 void TaskQueueImpl::PumpQueueLocked(bool may_post_dowork) { 460 void TaskQueueImpl::PumpQueueLocked(LazyNow* lazy_now, bool may_post_dowork) {
463 TRACE_EVENT1(disabled_by_default_tracing_category_, 461 TRACE_EVENT1(disabled_by_default_tracing_category_,
464 "TaskQueueImpl::PumpQueueLocked", "queue", name_); 462 "TaskQueueImpl::PumpQueueLocked", "queue", name_);
465 TaskQueueManager* task_queue_manager = any_thread().task_queue_manager; 463 TaskQueueManager* task_queue_manager = any_thread().task_queue_manager;
466 if (!task_queue_manager) 464 if (!task_queue_manager)
467 return; 465 return;
468 466
469 LazyNow lazy_now(main_thread_only().time_domain->CreateLazyNow()); 467 MoveReadyDelayedTasksToDelayedWorkQueue(lazy_now);
470 MoveReadyDelayedTasksToDelayedWorkQueue(&lazy_now);
471 468
472 while (!any_thread().immediate_incoming_queue.empty()) { 469 while (!any_thread().immediate_incoming_queue.empty()) {
473 main_thread_only().immediate_work_queue->Push( 470 main_thread_only().immediate_work_queue->Push(
474 std::move(any_thread().immediate_incoming_queue.front())); 471 std::move(any_thread().immediate_incoming_queue.front()));
475 any_thread().immediate_incoming_queue.pop(); 472 any_thread().immediate_incoming_queue.pop();
476 } 473 }
477 474
478 // |immediate_incoming_queue| is now empty so TimeDomain::UpdateQueues no 475 // |immediate_incoming_queue| is now empty so TimeDomain::UpdateQueues no
479 // longer needs to consider this queue for reloading. 476 // longer needs to consider this queue for reloading.
480 main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this); 477 main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this);
481 478
482 if (main_thread_only().immediate_work_queue->Empty() && 479 if (main_thread_only().immediate_work_queue->Empty() &&
483 main_thread_only().delayed_work_queue->Empty()) { 480 main_thread_only().delayed_work_queue->Empty()) {
484 return; 481 return;
485 } 482 }
486 483
487 if (may_post_dowork) 484 if (may_post_dowork)
488 task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); 485 task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
489 } 486 }
490 487
491 void TaskQueueImpl::PumpQueue(bool may_post_dowork) { 488 void TaskQueueImpl::PumpQueue(LazyNow* lazy_now, bool may_post_dowork) {
492 base::AutoLock lock(any_thread_lock_); 489 base::AutoLock lock(any_thread_lock_);
493 PumpQueueLocked(may_post_dowork); 490 PumpQueueLocked(lazy_now, may_post_dowork);
494 } 491 }
495 492
496 const char* TaskQueueImpl::GetName() const { 493 const char* TaskQueueImpl::GetName() const {
497 return name_; 494 return name_;
498 } 495 }
499 496
500 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) { 497 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) {
501 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority()) 498 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority())
502 return; 499 return;
503 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this, 500 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this,
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 state->SetBoolean("nestable", task.nestable); 696 state->SetBoolean("nestable", task.nestable);
700 state->SetBoolean("is_high_res", task.is_high_res); 697 state->SetBoolean("is_high_res", task.is_high_res);
701 state->SetDouble( 698 state->SetDouble(
702 "delayed_run_time", 699 "delayed_run_time",
703 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); 700 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
704 state->EndDictionary(); 701 state->EndDictionary();
705 } 702 }
706 703
707 } // namespace internal 704 } // namespace internal
708 } // namespace scheduler 705 } // namespace scheduler
OLDNEW
« no previous file with comments | « components/scheduler/base/task_queue_impl.h ('k') | components/scheduler/base/task_queue_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698