Chromium Code Reviews| Index: third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc |
| diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc |
| index 7a8da55f6de9817fac85eedcd6f3e781f0885529..77cf729b58f6b2127d1a3b9eb3503464719db9f4 100644 |
| --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc |
| +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc |
| @@ -216,12 +216,16 @@ bool TaskQueueImpl::PostDelayedTaskImpl( |
| void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( |
| Task pending_task, base::TimeTicks now) { |
| main_thread_only().task_queue_manager->DidQueueTask(pending_task); |
| - |
| - // Schedule a later call to MoveReadyDelayedTasksToDelayedWorkQueue. |
| - base::TimeTicks delayed_run_time = pending_task.delayed_run_time; |
| main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); |
| - main_thread_only().time_domain->ScheduleDelayedWork(this, delayed_run_time, |
| - now); |
| + |
| + // If |pending_task| is at the head of the queue, then make sure a wakeup |
| + // is requested. |
| + if (pending_task.delayed_run_time == |
|
Sami
2016/09/22 11:20:54
Looks like a use-after-move.
alex clarke (OOO till 29th)
2016/09/22 16:24:20
Done.
|
| + main_thread_only().delayed_incoming_queue.top().delayed_run_time) { |
| + main_thread_only().time_domain->ScheduleDelayedWork( |
| + this, pending_task.delayed_run_time, now); |
| + } |
| + |
| TraceQueueSize(false); |
| } |
| @@ -239,12 +243,33 @@ void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { |
| false); |
| } |
| +void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { |
| + DCHECK(main_thread_checker_.CalledOnValidThread()); |
| + base::TimeTicks delayed_run_time = pending_task.delayed_run_time; |
| + base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); |
| + if (delayed_run_time < time_domain_now) { |
| + // If |delayed_run_time| is in the past then push it onto the work queue |
| + // immediately. To ensure the right task ordering we need to temporarily |
| + // push it onto the |delayed_incoming_queue|. |
| + delayed_run_time = time_domain_now; |
| + pending_task.delayed_run_time = time_domain_now; |
| + main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); |
| + LazyNow lazy_now(time_domain_now); |
| + WakeUpForDelayedWork(&lazy_now); |
| + } else { |
| + // If |delayed_run_time| is in the future we can queue it as normal. |
| + PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task), |
| + time_domain_now); |
| + } |
| + TraceQueueSize(false); |
| +} |
| + |
| void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( |
| - const tracked_objects::Location& posted_from, |
| - const base::Closure& task, |
| - base::TimeTicks desired_run_time, |
| - EnqueueOrder sequence_number, |
| - bool nestable) { |
| + const tracked_objects::Location& posted_from, |
| + const base::Closure& task, |
| + base::TimeTicks desired_run_time, |
| + EnqueueOrder sequence_number, |
| + bool nestable) { |
| if (any_thread().immediate_incoming_queue.empty()) |
| any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); |
| // If the |immediate_incoming_queue| is empty we need a DoWork posted to make |
| @@ -265,25 +290,6 @@ void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( |
| TraceQueueSize(true); |
| } |
| -void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { |
| - DCHECK(main_thread_checker_.CalledOnValidThread()); |
| - base::TimeTicks delayed_run_time = pending_task.delayed_run_time; |
| - base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); |
| - // Make sure |delayed_run_time| isn't in the past. |
| - if (delayed_run_time < time_domain_now) { |
| - delayed_run_time = time_domain_now; |
| - pending_task.delayed_run_time = time_domain_now; |
| - main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); |
| - LazyNow lazy_now(time_domain_now); |
| - MoveReadyDelayedTasksToDelayedWorkQueue(&lazy_now); |
| - } else { |
| - main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); |
| - main_thread_only().time_domain->ScheduleDelayedWork( |
| - this, delayed_run_time, main_thread_only().time_domain->Now()); |
| - } |
| - TraceQueueSize(false); |
| -} |
| - |
| void TaskQueueImpl::SetQueueEnabled(bool enabled) { |
| if (main_thread_only().is_enabled == enabled) |
| return; |
| @@ -334,11 +340,10 @@ bool TaskQueueImpl::HasPendingImmediateWork() const { |
| return !any_thread().immediate_incoming_queue.empty(); |
| } |
| -void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now) { |
| +void TaskQueueImpl::WakeUpForDelayedWork(LazyNow* lazy_now) { |
| // Enqueue all delayed tasks that should be running now, skipping any that |
| // have been canceled. |
| while (!main_thread_only().delayed_incoming_queue.empty()) { |
| - // TODO(alexclarke): Use extract() when C++17 is allowed. |
| Task& task = |
| const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()); |
| if (task.task.IsCancelled()) { |
| @@ -352,6 +357,13 @@ void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now) { |
| main_thread_only().delayed_work_queue->Push(std::move(task)); |
| main_thread_only().delayed_incoming_queue.pop(); |
| } |
| + |
| + // Make sure the next wake up is scheduled. |
| + if (!main_thread_only().delayed_incoming_queue.empty()) { |
| + main_thread_only().time_domain->ScheduleDelayedWork( |
| + this, main_thread_only().delayed_incoming_queue.top().delayed_run_time, |
| + lazy_now->Now()); |
| + } |
| } |
| bool TaskQueueImpl::MaybeUpdateImmediateWorkQueues() { |
| @@ -452,6 +464,8 @@ void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { |
| state->SetDouble("delay_to_next_task_ms", |
| delay_to_next_task.InMillisecondsF()); |
| } |
| + if (main_thread_only().current_fence) |
| + state->SetInteger("current_fence", main_thread_only().current_fence); |
| if (verbose_tracing_enabled) { |
| state->BeginArray("immediate_incoming_queue"); |
| QueueAsValueInto(any_thread().immediate_incoming_queue, state); |