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); |