Index: third_party/WebKit/Source/platform/scheduler/renderer/throttling_helper.cc |
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/throttling_helper.cc b/third_party/WebKit/Source/platform/scheduler/renderer/throttling_helper.cc |
index 3e025e9dfdea4fcaa3383231290943d3fce5f0f4..d4bdb25cadc804297dff27cf39ddcc01bc13b7d4 100644 |
--- a/third_party/WebKit/Source/platform/scheduler/renderer/throttling_helper.cc |
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/throttling_helper.cc |
@@ -24,6 +24,7 @@ ThrottlingHelper::ThrottlingHelper(RendererSchedulerImpl* renderer_scheduler, |
tracing_category_(tracing_category), |
time_domain_(new ThrottledTimeDomain(this, tracing_category)), |
virtual_time_(false), |
+ ignore_incoming_immediate_work_(false), |
weak_factory_(this) { |
pump_throttled_tasks_closure_.Reset(base::Bind( |
&ThrottlingHelper::PumpThrottledTasks, weak_factory_.GetWeakPtr())); |
@@ -40,7 +41,6 @@ ThrottlingHelper::~ThrottlingHelper() { |
for (const TaskQueueMap::value_type& map_entry : throttled_queues_) { |
TaskQueue* task_queue = map_entry.first; |
task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain()); |
- task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); |
} |
renderer_scheduler_->UnregisterTimeDomain(time_domain_.get()); |
@@ -76,7 +76,6 @@ void ThrottlingHelper::IncreaseThrottleRefCount(TaskQueue* task_queue) { |
if (insert_result.second) { |
// The insert was succesful so we need to throttle the queue. |
task_queue->SetTimeDomain(time_domain_.get()); |
- task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); |
task_queue->SetQueueEnabled(false); |
if (!task_queue->IsEmpty()) { |
@@ -105,11 +104,14 @@ void ThrottlingHelper::DecreaseThrottleRefCount(TaskQueue* task_queue) { |
throttled_queues_.erase(iter); |
task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain()); |
- task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); |
task_queue->SetQueueEnabled(enabled); |
} |
} |
+bool ThrottlingHelper::IsThrottled(TaskQueue* task_queue) const { |
+ return throttled_queues_.find(task_queue) != throttled_queues_.end(); |
+} |
+ |
void ThrottlingHelper::UnregisterTaskQueue(TaskQueue* task_queue) { |
throttled_queues_.erase(task_queue); |
} |
@@ -120,6 +122,9 @@ void ThrottlingHelper::OnTimeDomainHasImmediateWork() { |
task_runner_->PostTask(FROM_HERE, forward_immediate_work_closure_); |
return; |
} |
+ // Posting ThrottlingHelper::MaybeDisableQueue doesn't count! |
Sami
2016/08/25 15:54:13
Isn't OnTimeDomainHasImmediateWork is only called
alex clarke (OOO till 29th)
2016/08/26 13:29:09
This has gone away.
|
+ if (ignore_incoming_immediate_work_) |
+ return; |
TRACE_EVENT0(tracing_category_, |
"ThrottlingHelper::OnTimeDomainHasImmediateWork"); |
base::TimeTicks now = tick_clock_->NowTicks(); |
@@ -143,14 +148,23 @@ void ThrottlingHelper::PumpThrottledTasks() { |
pending_pump_throttled_tasks_runtime_ = base::TimeTicks(); |
LazyNow lazy_low(tick_clock_); |
+ // Make sure posting MaybeDisableQueue doesn't trigger another pump. |
+ ignore_incoming_immediate_work_ = true; |
Sami
2016/08/25 15:54:13
nit: base::AutoReset?
alex clarke (OOO till 29th)
2016/08/26 13:29:08
This has gone away.
|
for (const TaskQueueMap::value_type& map_entry : throttled_queues_) { |
TaskQueue* task_queue = map_entry.first; |
- if (task_queue->IsEmpty()) |
+ if (task_queue->IsEmpty() || !map_entry.second.enabled) { |
Sami
2016/08/25 15:54:13
nit: might want to short-circuit .enabled first si
alex clarke (OOO till 29th)
2016/08/26 13:29:09
Done.
|
continue; |
+ } |
- task_queue->SetQueueEnabled(map_entry.second.enabled); |
- task_queue->PumpQueue(&lazy_low, false); |
+ // Post a task to disable |task_queue|, which ensures that no tasks posted |
+ // after this point will be run until next time. |
+ task_queue->PostTask(FROM_HERE, |
Sami
2016/08/25 15:54:13
Could IsEmpty() above get fooled by this task that
alex clarke (OOO till 29th)
2016/08/26 13:29:09
This has gone away.
|
+ base::Bind(&ThrottlingHelper::MaybeDisableQueue, |
+ weak_factory_.GetWeakPtr(), task_queue)); |
+ task_queue->SetQueueEnabled(true); |
} |
+ ignore_incoming_immediate_work_ = false; |
+ |
// Make sure NextScheduledRunTime gives us an up-to date result. |
time_domain_->ClearExpiredWakeups(); |
@@ -164,6 +178,23 @@ void ThrottlingHelper::PumpThrottledTasks() { |
} |
} |
+void ThrottlingHelper::MaybeDisableQueue(TaskQueue* task_queue) { |
+ // It's quite possible the queue is no longer throttled in which case we |
+ // should bail out. |
+ if (throttled_queues_.find(task_queue) == throttled_queues_.end()) |
Sami
2016/08/25 15:54:13
nit: Could call IsThrottled()
alex clarke (OOO till 29th)
2016/08/26 13:29:09
This has gone away.
|
+ return; |
+ |
+ task_queue->SetQueueEnabled(false); |
+ |
+ // Normally ThrottlingHelper::OnTimeDomainHasImmediateWork would detect |
+ // extra work, but that call only happens if the queue was empty. So |
+ // We need an extra check here to determine if there's more work to do. |
+ if (task_queue->HasPendingImmediateWork()) { |
+ base::TimeTicks now = tick_clock_->NowTicks(); |
+ MaybeSchedulePumpThrottledTasksLocked(FROM_HERE, now, now); |
+ } |
+} |
+ |
/* static */ |
base::TimeTicks ThrottlingHelper::ThrottledRunTime( |
base::TimeTicks unthrottled_runtime) { |
@@ -212,7 +243,6 @@ void ThrottlingHelper::EnableVirtualTime() { |
throttled_queues_.erase(throttled_queues_.begin()); |
task_queue->SetTimeDomain(renderer_scheduler_->GetVirtualTimeDomain()); |
- task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); |
task_queue->SetQueueEnabled(enabled); |
} |
} |