Chromium Code Reviews| 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..9f25dd1d3a9b8839102a23e6bb1fe341cab0fdd0 100644 |
| --- a/content/renderer/scheduler/task_queue_manager.cc |
| +++ b/content/renderer/scheduler/task_queue_manager.cc |
| @@ -43,7 +43,7 @@ class TaskQueue : public base::SingleThreadTaskRunner { |
| void PumpQueue(); |
| bool UpdateWorkQueue(base::TimeTicks* next_pending_delayed_task, |
| - TaskQueueManager::WorkQueueUpdateEventType event_type); |
| + const base::PendingTask* previous_task); |
| base::PendingTask TakeTaskFromWorkQueue(); |
| void WillDeleteTaskQueueManager(); |
| @@ -73,8 +73,8 @@ class TaskQueue : public base::SingleThreadTaskRunner { |
| void EnqueueTask(const base::PendingTask& pending_task); |
| void PumpQueueLocked(); |
| - bool ShouldAutoPumpQueueLocked( |
| - TaskQueueManager::WorkQueueUpdateEventType event_type); |
| + bool TaskIsOlderThanQueuedTasks(const base::PendingTask* task); |
| + bool ShouldAutoPumpQueueLocked(const base::PendingTask* previous_task); |
| void EnqueueTaskLocked(const base::PendingTask& pending_task); |
| void TraceQueueSize(bool is_locked) const; |
| @@ -153,13 +153,31 @@ bool TaskQueue::IsQueueEmpty() const { |
| } |
| } |
| +bool TaskQueue::TaskIsOlderThanQueuedTasks(const base::PendingTask* task) { |
| + lock_.AssertAcquired(); |
| + // Always return true if passed a NULL task. |
| + if (task == NULL) |
|
picksi
2015/03/02 14:30:06
Is this to protect against null-pointer deferencin
Sami
2015/03/02 14:48:46
Also, I think we're using nullptr now, although "(
rmcilroy
2015/03/02 15:34:51
Very true (the comment added more before I explici
rmcilroy
2015/03/02 15:34:52
Done.
|
| + return true; |
| + |
| + // Return false if there are no task in the incoming queue. |
| + if (incoming_queue_.empty()) |
| + return false; |
| + |
| + base::PendingTask oldest_queued_task = incoming_queue_.front(); |
| + |
| + // Note: the comparison is correct due to the fact that the PendingTask |
| + // operator inverts its comparison operation in order to work well in a heap |
| + // based priority queue. |
| + return oldest_queued_task < *task; |
| +} |
| + |
| bool TaskQueue::ShouldAutoPumpQueueLocked( |
| - TaskQueueManager::WorkQueueUpdateEventType event_type) { |
| + const base::PendingTask* previous_task) { |
| lock_.AssertAcquired(); |
| if (pump_policy_ == TaskQueueManager::PumpPolicy::MANUAL) |
| return false; |
| if (pump_policy_ == TaskQueueManager::PumpPolicy::AFTER_WAKEUP && |
| - event_type != TaskQueueManager::WorkQueueUpdateEventType::AFTER_WAKEUP) |
| + TaskIsOlderThanQueuedTasks(previous_task)) |
| return false; |
| if (incoming_queue_.empty()) |
| return false; |
| @@ -168,7 +186,7 @@ bool TaskQueue::ShouldAutoPumpQueueLocked( |
| bool TaskQueue::UpdateWorkQueue( |
| base::TimeTicks* next_pending_delayed_task, |
| - TaskQueueManager::WorkQueueUpdateEventType event_type) { |
| + const base::PendingTask* previous_task) { |
| if (!work_queue_.empty()) |
| return true; |
| @@ -178,7 +196,7 @@ bool TaskQueue::UpdateWorkQueue( |
| *next_pending_delayed_task = |
| std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); |
| } |
| - if (!ShouldAutoPumpQueueLocked(event_type)) |
| + if (!ShouldAutoPumpQueueLocked(previous_task)) |
| return false; |
| work_queue_.Swap(&incoming_queue_); |
| TraceQueueSize(true); |
| @@ -383,14 +401,15 @@ void TaskQueueManager::PumpQueue(size_t queue_index) { |
| bool TaskQueueManager::UpdateWorkQueues( |
| base::TimeTicks* next_pending_delayed_task, |
| - WorkQueueUpdateEventType event_type) { |
| + const base::PendingTask* previous_task) { |
| // TODO(skyostil): This is not efficient when the number of queues grows very |
| // large due to the number of locks taken. Consider optimizing when we get |
| // there. |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| bool has_work = false; |
| for (auto& queue : queues_) { |
| - has_work |= queue->UpdateWorkQueue(next_pending_delayed_task, event_type); |
| + has_work |= queue->UpdateWorkQueue(next_pending_delayed_task, |
| + previous_task); |
| if (!queue->work_queue().empty()) { |
| // Currently we should not be getting tasks with delayed run times in any |
| // of the work queues. |
| @@ -425,13 +444,12 @@ void TaskQueueManager::DoWork(bool posted_from_main_thread) { |
| base::TimeTicks next_pending_delayed_task( |
| base::TimeTicks::FromInternalValue(kMaxTimeTicks)); |
| + base::PendingTask previous_task((tracked_objects::Location()), |
| + (base::Closure())); |
| - if (!UpdateWorkQueues(&next_pending_delayed_task, |
| - WorkQueueUpdateEventType::BEFORE_WAKEUP)) |
| + if (!UpdateWorkQueues(&next_pending_delayed_task, NULL)) |
|
picksi
2015/03/02 14:30:06
Can you add a comment/const to make it clear what
Sami
2015/03/02 14:48:46
nullptr here too.
rmcilroy
2015/03/02 15:34:51
Done.
rmcilroy
2015/03/02 15:34:51
Done.
|
| return; |
| - base::PendingTask previous_task((tracked_objects::Location()), |
| - (base::Closure())); |
| for (int i = 0; i < work_batch_size_; i++) { |
| // Interrupt the work batch if we should run the next delayed task. |
| if (i > 0 && next_pending_delayed_task.ToInternalValue() != kMaxTimeTicks && |
| @@ -446,8 +464,7 @@ void TaskQueueManager::DoWork(bool posted_from_main_thread) { |
| MaybePostDoWorkOnMainRunner(); |
| ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task); |
| - if (!UpdateWorkQueues(&next_pending_delayed_task, |
| - WorkQueueUpdateEventType::AFTER_WAKEUP)) |
| + if (!UpdateWorkQueues(&next_pending_delayed_task, &previous_task)) |
| return; |
| } |
| } |