Chromium Code Reviews| Index: third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc |
| diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc |
| index 406b9598ad81fbbedfe67b11905675c9b9881d8b..0987a2de209026d817ecce64ec9a46c58278ac77 100644 |
| --- a/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc |
| +++ b/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc |
| @@ -25,9 +25,9 @@ IdleHelper::IdleHelper( |
| base::TimeDelta required_quiescence_duration_before_long_idle_period) |
| : helper_(helper), |
| delegate_(delegate), |
| - idle_queue_( |
| - helper_->NewTaskQueue(TaskQueue::Spec("idle_tq").SetPumpPolicy( |
| - TaskQueue::PumpPolicy::MANUAL))), |
| + idle_queue_(helper_->NewTaskQueue(TaskQueue::Spec("idle_tq"))), |
| + non_nestable_idle_queue_( |
| + helper_->NewTaskQueue(TaskQueue::Spec("non_nestable_idle_tq"))), |
| state_(helper, |
| delegate, |
| tracing_category, |
| @@ -43,13 +43,18 @@ IdleHelper::IdleHelper( |
| base::Bind(&IdleHelper::EnableLongIdlePeriod, weak_idle_helper_ptr_)); |
| on_idle_task_posted_closure_.Reset(base::Bind( |
| &IdleHelper::OnIdleTaskPostedOnMainThread, weak_idle_helper_ptr_)); |
| + disable_idle_queue_closure_.Reset( |
| + base::Bind(&IdleHelper::DisableIdleTaskQueueTask, weak_idle_helper_ptr_)); |
| + disable_non_nestable_idle_queue_closure_.Reset(base::Bind( |
| + &IdleHelper::DisableNonNestableIdleTaskQueueTask, weak_idle_helper_ptr_)); |
| idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( |
| - idle_queue_, helper_->ControlAfterWakeUpTaskRunner(), this, |
| - tracing_category)); |
| + idle_queue_, non_nestable_idle_queue_, this, tracing_category)); |
| idle_queue_->SetQueueEnabled(false); |
| idle_queue_->SetQueuePriority(TaskQueue::BEST_EFFORT_PRIORITY); |
| + non_nestable_idle_queue_->SetQueueEnabled(false); |
| + non_nestable_idle_queue_->SetQueuePriority(TaskQueue::BEST_EFFORT_PRIORITY); |
| helper_->AddTaskObserver(this); |
| } |
| @@ -62,6 +67,20 @@ IdleHelper::Delegate::Delegate() {} |
| IdleHelper::Delegate::~Delegate() {} |
| +void IdleHelper::DisableIdleTaskQueueTask() { |
| + idle_queue_->SetQueueEnabled(false); |
| + if (IsInLongIdlePeriod(state_.idle_period_state())) { |
| + UpdateLongIdlePeriodStateAfterIdleTask(); |
| + } |
| +} |
| + |
| +void IdleHelper::DisableNonNestableIdleTaskQueueTask() { |
| + non_nestable_idle_queue_->SetQueueEnabled(false); |
| + if (IsInLongIdlePeriod(state_.idle_period_state())) { |
| + UpdateLongIdlePeriodStateAfterIdleTask(); |
| + } |
| +} |
| + |
| scoped_refptr<SingleThreadIdleTaskRunner> IdleHelper::IdleTaskRunner() { |
| helper_->CheckOnValidThread(); |
| return idle_task_runner_; |
| @@ -115,8 +134,9 @@ bool IdleHelper::ShouldWaitForQuiescence() { |
| return false; |
| if (required_quiescence_duration_before_long_idle_period_ == |
| - base::TimeDelta()) |
| + base::TimeDelta()) { |
| return false; |
| + } |
| bool system_is_quiescent = helper_->GetAndClearSystemIsQuiescentBit(); |
| TRACE_EVENT1(disabled_by_default_tracing_category_, "ShouldWaitForQuiescence", |
| @@ -174,9 +194,21 @@ void IdleHelper::StartIdlePeriod(IdlePeriodState new_state, |
| } |
| TRACE_EVENT0(disabled_by_default_tracing_category_, "StartIdlePeriod"); |
| - idle_queue_->SetQueueEnabled(true); |
| - LazyNow lazy_now(now); |
| - idle_queue_->PumpQueue(&lazy_now, true); |
| + |
| + // Make sure any idle tasks poster after this do not run until the next idle |
| + // period. With nested message loops it's possible there are pending disable |
| + // tasks, we don't want that so cancel them. |
| + disable_idle_queue_closure_.Cancel(); |
| + disable_non_nestable_idle_queue_closure_.Cancel(); |
| + if (idle_queue_->HasPendingImmediateWork()) { |
| + idle_queue_->PostTask(FROM_HERE, disable_idle_queue_closure_.callback()); |
|
Sami
2016/08/25 15:54:12
I wonder if this could have a failure mode where w
alex clarke (OOO till 29th)
2016/08/26 13:29:08
I've replaced this mechanism with something akin t
|
| + idle_queue_->SetQueueEnabled(true); |
| + } |
| + if (non_nestable_idle_queue_->HasPendingImmediateWork()) { |
| + non_nestable_idle_queue_->PostNonNestableTask( |
| + FROM_HERE, disable_non_nestable_idle_queue_closure_.callback()); |
| + non_nestable_idle_queue_->SetQueueEnabled(true); |
| + } |
| state_.UpdateState(new_state, idle_period_deadline, now); |
| } |
| @@ -192,7 +224,12 @@ void IdleHelper::EndIdlePeriod() { |
| if (!IsInIdlePeriod(state_.idle_period_state())) |
| return; |
| + // Cancel any pending calls to disable the idle queues in favor of disabling |
| + // now. |
| + disable_idle_queue_closure_.Cancel(); |
|
Sami
2016/08/25 15:54:13
This means we might not run UpdateLongIdlePeriodSt
alex clarke (OOO till 29th)
2016/08/26 13:29:08
Acknowledged.
|
| + disable_non_nestable_idle_queue_closure_.Cancel(); |
| idle_queue_->SetQueueEnabled(false); |
| + non_nestable_idle_queue_->SetQueueEnabled(false); |
| state_.UpdateState(IdlePeriodState::NOT_IN_IDLE_PERIOD, base::TimeTicks(), |
| base::TimeTicks()); |
| } |
| @@ -230,7 +267,7 @@ void IdleHelper::UpdateLongIdlePeriodStateAfterIdleTask() { |
| // new idle task is posted. |
| state_.UpdateState(IdlePeriodState::IN_LONG_IDLE_PERIOD_PAUSED, |
| state_.idle_period_deadline(), base::TimeTicks()); |
| - } else if (idle_queue_->NeedsPumping()) { |
| + } else if (!idle_queue_->IsEmpty()) { |
| // If there is still idle work to do then just start the next idle period. |
| base::TimeDelta next_long_idle_period_delay; |
| if (state_.idle_period_state() == |
| @@ -290,9 +327,6 @@ base::TimeTicks IdleHelper::WillProcessIdleTask() { |
| void IdleHelper::DidProcessIdleTask() { |
| helper_->CheckOnValidThread(); |
| state_.TraceIdleIdleTaskEnd(); |
| - if (IsInLongIdlePeriod(state_.idle_period_state())) { |
| - UpdateLongIdlePeriodStateAfterIdleTask(); |
| - } |
| } |
| // static |