| Index: content/renderer/scheduler/task_queue_manager.cc
|
| diff --git a/content/renderer/scheduler/task_queue_manager.cc b/content/renderer/scheduler/task_queue_manager.cc
|
| index f4f8fc5f8f28a2ee01e57836107ff7658dab50df..1d394049197dda69c1ff7b4991604b572d5763f1 100644
|
| --- a/content/renderer/scheduler/task_queue_manager.cc
|
| +++ b/content/renderer/scheduler/task_queue_manager.cc
|
| @@ -5,6 +5,7 @@
|
| #include "content/renderer/scheduler/task_queue_manager.h"
|
|
|
| #include <queue>
|
| +#include <set>
|
|
|
| #include "base/bind.h"
|
| #include "base/trace_event/trace_event.h"
|
| @@ -67,10 +68,11 @@ class TaskQueue : public base::SingleThreadTaskRunner {
|
| base::TimeDelta delay,
|
| TaskType task_type);
|
|
|
| - // Adds a task at the end of the incoming task queue and schedules a call to
|
| - // TaskQueueManager::DoWork() if the incoming queue was empty and automatic
|
| - // pumping is enabled. Can be called on an arbitrary thread.
|
| - void EnqueueTask(const base::PendingTask& pending_task);
|
| + // Adds delayed_task_queue_.top() at the end of the incoming task queue and
|
| + // schedules a call to TaskQueueManager::DoWork() if the incoming queue was
|
| + // empty and automatic pumping is enabled. Can be called on an arbitrary
|
| + // thread.
|
| + void EnqueueNextPendingTask();
|
|
|
| void PumpQueueLocked();
|
| bool ShouldAutoPumpQueueLocked(
|
| @@ -91,9 +93,7 @@ class TaskQueue : public base::SingleThreadTaskRunner {
|
| base::TaskQueue incoming_queue_;
|
| TaskQueueManager::PumpPolicy pump_policy_;
|
| const char* name_;
|
| - std::priority_queue<base::TimeTicks,
|
| - std::vector<base::TimeTicks>,
|
| - std::greater<base::TimeTicks>> delayed_task_run_times_;
|
| + base::DelayedTaskQueue delayed_task_queue_;
|
|
|
| base::TaskQueue work_queue_;
|
|
|
| @@ -112,6 +112,11 @@ TaskQueue::~TaskQueue() {
|
| void TaskQueue::WillDeleteTaskQueueManager() {
|
| base::AutoLock lock(lock_);
|
| task_queue_manager_ = nullptr;
|
| +
|
| + // Clear all delayed tasks because we need them to be deleted before the blink
|
| + // heap goes away.
|
| + while (!delayed_task_queue_.empty())
|
| + delayed_task_queue_.pop();
|
| }
|
|
|
| bool TaskQueue::RunsTasksOnCurrentThread() const {
|
| @@ -135,9 +140,9 @@ bool TaskQueue::PostDelayedTaskImpl(const tracked_objects::Location& from_here,
|
|
|
| if (delay > base::TimeDelta()) {
|
| pending_task.delayed_run_time = task_queue_manager_->Now() + delay;
|
| - delayed_task_run_times_.push(pending_task.delayed_run_time);
|
| + delayed_task_queue_.push(pending_task);
|
| return task_queue_manager_->PostDelayedTask(
|
| - FROM_HERE, Bind(&TaskQueue::EnqueueTask, this, pending_task), delay);
|
| + FROM_HERE, Bind(&TaskQueue::EnqueueNextPendingTask, this), delay);
|
| }
|
| EnqueueTaskLocked(pending_task);
|
| return true;
|
| @@ -174,9 +179,10 @@ bool TaskQueue::UpdateWorkQueue(
|
|
|
| {
|
| base::AutoLock lock(lock_);
|
| - if (!delayed_task_run_times_.empty()) {
|
| + if (!delayed_task_queue_.empty()) {
|
| *next_pending_delayed_task =
|
| - std::min(*next_pending_delayed_task, delayed_task_run_times_.top());
|
| + std::min(*next_pending_delayed_task,
|
| + delayed_task_queue_.top().delayed_run_time);
|
| }
|
| if (!ShouldAutoPumpQueueLocked(event_type))
|
| return false;
|
| @@ -209,9 +215,16 @@ void TaskQueue::TraceQueueSize(bool is_locked) const {
|
| lock_.Release();
|
| }
|
|
|
| -void TaskQueue::EnqueueTask(const base::PendingTask& pending_task) {
|
| +void TaskQueue::EnqueueNextPendingTask() {
|
| base::AutoLock lock(lock_);
|
| - EnqueueTaskLocked(pending_task);
|
| + if (!task_queue_manager_)
|
| + return;
|
| +
|
| + if (delayed_task_queue_.empty())
|
| + return;
|
| +
|
| + EnqueueTaskLocked(delayed_task_queue_.top());
|
| + delayed_task_queue_.pop();
|
| }
|
|
|
| void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) {
|
| @@ -224,11 +237,6 @@ void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) {
|
| incoming_queue_.push(pending_task);
|
|
|
| if (!pending_task.delayed_run_time.is_null()) {
|
| - // Update the time of the next pending delayed task.
|
| - while (!delayed_task_run_times_.empty() &&
|
| - delayed_task_run_times_.top() <= pending_task.delayed_run_time) {
|
| - delayed_task_run_times_.pop();
|
| - }
|
| // Clear the delayed run time because we've already applied the delay
|
| // before getting here.
|
| incoming_queue_.back().delayed_run_time = base::TimeTicks();
|
|
|