| 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 26d6c36eb5c1d61d07485d4620be4a866a030763..11976b7221d598d6fdc95040a0c00e91bb222fa1 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
 | 
| @@ -5,6 +5,7 @@
 | 
|  #include "platform/scheduler/base/task_queue_impl.h"
 | 
|  
 | 
|  #include "base/format_macros.h"
 | 
| +#include "base/memory/ptr_util.h"
 | 
|  #include "base/strings/stringprintf.h"
 | 
|  #include "base/trace_event/blame_context.h"
 | 
|  #include "platform/scheduler/base/task_queue_manager.h"
 | 
| @@ -156,7 +157,8 @@ TaskQueueImpl::MainThreadOnly::MainThreadOnly(
 | 
|        delayed_work_queue(new WorkQueue(task_queue, "delayed")),
 | 
|        immediate_work_queue(new WorkQueue(task_queue, "immediate")),
 | 
|        set_index(0),
 | 
| -      is_enabled(true),
 | 
| +      is_enabled_refcount(0),
 | 
| +      voter_refcount(0),
 | 
|        blame_context(nullptr),
 | 
|        current_fence(0) {}
 | 
|  
 | 
| @@ -332,7 +334,7 @@ void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
 | 
|      // There's no point posting a DoWork for a disabled queue, however we can
 | 
|      // only tell if it's disabled from the main thread.
 | 
|      if (base::PlatformThread::CurrentId() == thread_id_) {
 | 
| -      if (main_thread_only().is_enabled && !BlockedByFenceLocked())
 | 
| +      if (IsQueueEnabled() && !BlockedByFenceLocked())
 | 
|          any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
 | 
|      } else {
 | 
|        any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
 | 
| @@ -344,25 +346,6 @@ void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
 | 
|    TraceQueueSize(true);
 | 
|  }
 | 
|  
 | 
| -void TaskQueueImpl::SetQueueEnabled(bool enabled) {
 | 
| -  if (main_thread_only().is_enabled == enabled)
 | 
| -    return;
 | 
| -  main_thread_only().is_enabled = enabled;
 | 
| -  if (!main_thread_only().task_queue_manager)
 | 
| -    return;
 | 
| -  if (enabled) {
 | 
| -    // Note it's the job of the selector to tell the TaskQueueManager if
 | 
| -    // a DoWork needs posting.
 | 
| -    main_thread_only().task_queue_manager->selector_.EnableQueue(this);
 | 
| -  } else {
 | 
| -    main_thread_only().task_queue_manager->selector_.DisableQueue(this);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -bool TaskQueueImpl::IsQueueEnabled() const {
 | 
| -  return main_thread_only().is_enabled;
 | 
| -}
 | 
| -
 | 
|  bool TaskQueueImpl::IsEmpty() const {
 | 
|    if (!main_thread_only().delayed_work_queue->Empty() ||
 | 
|        !main_thread_only().delayed_incoming_queue.empty() ||
 | 
| @@ -506,7 +489,7 @@ void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
 | 
|        "task_queue_id",
 | 
|        base::StringPrintf("%" PRIx64, static_cast<uint64_t>(
 | 
|                                           reinterpret_cast<uintptr_t>(this))));
 | 
| -  state->SetBoolean("enabled", main_thread_only().is_enabled);
 | 
| +  state->SetBoolean("enabled", IsQueueEnabled());
 | 
|    state->SetString("time_domain_name",
 | 
|                     main_thread_only().time_domain->GetName());
 | 
|    bool verbose_tracing_enabled = false;
 | 
| @@ -640,7 +623,7 @@ void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) {
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  if (main_thread_only().is_enabled && task_unblocked) {
 | 
| +  if (IsQueueEnabled() && task_unblocked) {
 | 
|      main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
 | 
|          FROM_HERE);
 | 
|    }
 | 
| @@ -665,7 +648,7 @@ void TaskQueueImpl::RemoveFence() {
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  if (main_thread_only().is_enabled && task_unblocked) {
 | 
| +  if (IsQueueEnabled() && task_unblocked) {
 | 
|      main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
 | 
|          FROM_HERE);
 | 
|    }
 | 
| @@ -760,6 +743,83 @@ void TaskQueueImpl::TaskAsValueInto(const Task& task,
 | 
|    state->EndDictionary();
 | 
|  }
 | 
|  
 | 
| +TaskQueueImpl::QueueEnabledVoterImpl::QueueEnabledVoterImpl(
 | 
| +    TaskQueueImpl* task_queue)
 | 
| +    : task_queue_(task_queue), enabled_(true) {}
 | 
| +
 | 
| +TaskQueueImpl::QueueEnabledVoterImpl::~QueueEnabledVoterImpl() {
 | 
| +  task_queue_->RemoveQueueEnabledVoter(this);
 | 
| +}
 | 
| +
 | 
| +TaskQueue* TaskQueueImpl::QueueEnabledVoterImpl::GetTaskQueue() const {
 | 
| +  return task_queue_.get();
 | 
| +}
 | 
| +
 | 
| +void TaskQueueImpl::QueueEnabledVoterImpl::SetQueueEnabled(bool enabled) {
 | 
| +  if (enabled_ == enabled)
 | 
| +    return;
 | 
| +
 | 
| +  task_queue_->QueueEnabledVoteChanged(enabled);
 | 
| +  enabled_ = enabled;
 | 
| +}
 | 
| +
 | 
| +void TaskQueueImpl::RemoveQueueEnabledVoter(
 | 
| +    const QueueEnabledVoterImpl* voter) {
 | 
| +  bool was_enabled = IsQueueEnabled();
 | 
| +  if (voter->enabled_) {
 | 
| +    main_thread_only().is_enabled_refcount--;
 | 
| +    DCHECK_GE(main_thread_only().is_enabled_refcount, 0);
 | 
| +  }
 | 
| +
 | 
| +  main_thread_only().voter_refcount--;
 | 
| +  DCHECK_GE(main_thread_only().voter_refcount, 0);
 | 
| +
 | 
| +  bool is_enabled = IsQueueEnabled();
 | 
| +  if (was_enabled != is_enabled)
 | 
| +    EnableOrDisableWithSelector(is_enabled);
 | 
| +}
 | 
| +
 | 
| +bool TaskQueueImpl::IsQueueEnabled() const {
 | 
| +  return main_thread_only().is_enabled_refcount ==
 | 
| +         main_thread_only().voter_refcount;
 | 
| +}
 | 
| +
 | 
| +void TaskQueueImpl::QueueEnabledVoteChanged(bool enabled) {
 | 
| +  bool was_enabled = IsQueueEnabled();
 | 
| +  if (enabled) {
 | 
| +    main_thread_only().is_enabled_refcount++;
 | 
| +    DCHECK_LE(main_thread_only().is_enabled_refcount,
 | 
| +              main_thread_only().voter_refcount);
 | 
| +  } else {
 | 
| +    main_thread_only().is_enabled_refcount--;
 | 
| +    DCHECK_GE(main_thread_only().is_enabled_refcount, 0);
 | 
| +  }
 | 
| +
 | 
| +  bool is_enabled = IsQueueEnabled();
 | 
| +  if (was_enabled != is_enabled)
 | 
| +    EnableOrDisableWithSelector(is_enabled);
 | 
| +}
 | 
| +
 | 
| +void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) {
 | 
| +  if (!main_thread_only().task_queue_manager)
 | 
| +    return;
 | 
| +
 | 
| +  if (enable) {
 | 
| +    // Note it's the job of the selector to tell the TaskQueueManager if
 | 
| +    // a DoWork needs posting.
 | 
| +    main_thread_only().task_queue_manager->selector_.EnableQueue(this);
 | 
| +  } else {
 | 
| +    main_thread_only().task_queue_manager->selector_.DisableQueue(this);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +std::unique_ptr<TaskQueueImpl::QueueEnabledVoter>
 | 
| +TaskQueueImpl::GetQueueEnabledVoter() {
 | 
| +  main_thread_only().voter_refcount++;
 | 
| +  main_thread_only().is_enabled_refcount++;
 | 
| +  return base::MakeUnique<QueueEnabledVoterImpl>(this);
 | 
| +}
 | 
| +
 | 
|  }  // namespace internal
 | 
|  }  // namespace scheduler
 | 
|  }  // namespace blink
 | 
| 
 |