| 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 b534f5179759da5509ce80c1d50b6c27dd8e7759..1493997a88f4d3df7e54b516aa0d679bf447a000 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
|
| @@ -93,7 +93,7 @@ TaskQueueImpl::TaskQueueImpl(
|
|
|
| TaskQueueImpl::~TaskQueueImpl() {
|
| #if DCHECK_IS_ON()
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| // NOTE this check shouldn't fire because |TaskQueueManager::queues_|
|
| // contains a strong reference to this TaskQueueImpl and the TaskQueueManager
|
| // destructor calls UnregisterTaskQueue on all task queues.
|
| @@ -163,12 +163,13 @@ TaskQueueImpl::MainThreadOnly::MainThreadOnly(
|
| is_enabled_refcount(0),
|
| voter_refcount(0),
|
| blame_context(nullptr),
|
| - current_fence(0) {}
|
| + current_fence(0),
|
| + any_thread_lock_acquired_count(0) {}
|
|
|
| TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {}
|
|
|
| void TaskQueueImpl::UnregisterTaskQueue() {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| if (main_thread_only().time_domain)
|
| main_thread_only().time_domain->UnregisterQueue(this);
|
| if (!any_thread().task_queue_manager)
|
| @@ -212,7 +213,7 @@ bool TaskQueueImpl::PostImmediateTaskImpl(
|
| const tracked_objects::Location& from_here,
|
| const base::Closure& task,
|
| TaskType task_type) {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| if (!any_thread().task_queue_manager)
|
| return false;
|
|
|
| @@ -253,7 +254,7 @@ bool TaskQueueImpl::PostDelayedTaskImpl(
|
| // be common. This pathway is less optimal than perhaps it could be
|
| // because it causes two main thread tasks to be run. Should this
|
| // assumption prove to be false in future, we may need to revisit this.
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| if (!any_thread().task_queue_manager)
|
| return false;
|
|
|
| @@ -358,7 +359,7 @@ void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() {
|
| }
|
|
|
| WTF::Deque<TaskQueueImpl::Task> TaskQueueImpl::TakeImmediateIncomingQueue() {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| WTF::Deque<TaskQueueImpl::Task> queue;
|
| queue.swap(any_thread().immediate_incoming_queue);
|
| return queue;
|
| @@ -371,7 +372,7 @@ bool TaskQueueImpl::IsEmpty() const {
|
| return false;
|
| }
|
|
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| return any_thread().immediate_incoming_queue.empty();
|
| }
|
|
|
| @@ -381,7 +382,7 @@ size_t TaskQueueImpl::GetNumberOfPendingTasks() const {
|
| task_count += main_thread_only().delayed_incoming_queue.size();
|
| task_count += main_thread_only().immediate_work_queue->Size();
|
|
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| task_count += any_thread().immediate_incoming_queue.size();
|
| return task_count;
|
| }
|
| @@ -402,7 +403,7 @@ bool TaskQueueImpl::HasPendingImmediateWork() const {
|
| }
|
|
|
| // Finally tasks on |immediate_incoming_queue| count as immediate work.
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| return !any_thread().immediate_incoming_queue.empty();
|
| }
|
|
|
| @@ -490,7 +491,7 @@ TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const {
|
| }
|
|
|
| void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| state->BeginDictionary();
|
| state->SetString("name", GetName());
|
| state->SetString(
|
| @@ -568,7 +569,7 @@ void TaskQueueImpl::NotifyDidProcessTask(
|
|
|
| void TaskQueueImpl::SetTimeDomain(TimeDomain* time_domain) {
|
| {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| DCHECK(time_domain);
|
| // NOTE this is similar to checking |any_thread().task_queue_manager| but
|
| // the TaskQueueSelectorTests constructs TaskQueueImpl directly with a null
|
| @@ -601,7 +602,7 @@ TimeDomain* TaskQueueImpl::GetTimeDomain() const {
|
| if (base::PlatformThread::CurrentId() == thread_id_)
|
| return main_thread_only().time_domain;
|
|
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| return any_thread().time_domain;
|
| }
|
|
|
| @@ -629,7 +630,7 @@ void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) {
|
|
|
| if (!task_unblocked && previous_fence &&
|
| previous_fence < main_thread_only().current_fence) {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| if (!any_thread().immediate_incoming_queue.empty() &&
|
| any_thread().immediate_incoming_queue.front().enqueue_order() >
|
| previous_fence &&
|
| @@ -656,7 +657,7 @@ void TaskQueueImpl::RemoveFence() {
|
| task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence();
|
|
|
| if (!task_unblocked && previous_fence) {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| if (!any_thread().immediate_incoming_queue.empty() &&
|
| any_thread().immediate_incoming_queue.front().enqueue_order() >
|
| previous_fence) {
|
| @@ -679,7 +680,7 @@ bool TaskQueueImpl::BlockedByFence() const {
|
| return false;
|
| }
|
|
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| if (any_thread().immediate_incoming_queue.empty())
|
| return true;
|
|
|
| @@ -812,7 +813,7 @@ void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) {
|
| bool immediate_queues_empty =
|
| main_thread_only().immediate_work_queue->Empty();
|
| if (immediate_queues_empty) {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| immediate_queues_empty = any_thread().immediate_incoming_queue.empty();
|
| }
|
| // Avoid holding the lock while we fire the notification.
|
| @@ -879,10 +880,38 @@ void TaskQueueImpl::SweepCanceledDelayedTasks(base::TimeTicks now) {
|
|
|
| void TaskQueueImpl::PushImmediateIncomingTaskForTest(
|
| TaskQueueImpl::Task&& task) {
|
| - base::AutoLock lock(any_thread_lock_);
|
| + AnyThreadAutoLock lock = AcquireAnyThreadLock();
|
| any_thread().immediate_incoming_queue.push_back(std::move(task));
|
| }
|
|
|
| +TaskQueueImpl::AnyThreadAutoLock TaskQueueImpl::AcquireAnyThreadLock() const {
|
| + size_t* any_thread_lock_acquired_from_main_thread_count = nullptr;
|
| + if (thread_id_ == base::PlatformThread::CurrentId())
|
| + any_thread_lock_acquired_from_main_thread_count =
|
| + &main_thread_only().any_thread_lock_acquired_count;
|
| + return AnyThreadAutoLock(any_thread_lock_,
|
| + any_thread_lock_acquired_from_main_thread_count);
|
| +}
|
| +
|
| +TaskQueueImpl::AnyThreadAutoLock::AnyThreadAutoLock(base::Lock& lock,
|
| + size_t* acquired_count)
|
| + : lock_(lock), acquired_count_(acquired_count) {
|
| + if (!acquired_count_ || *acquired_count_ == 0) {
|
| + lock_.Acquire();
|
| + }
|
| + if (acquired_count_)
|
| + ++*acquired_count_;
|
| + lock_.AssertAcquired();
|
| +}
|
| +
|
| +TaskQueueImpl::AnyThreadAutoLock::~AnyThreadAutoLock() {
|
| + lock_.AssertAcquired();
|
| + if (acquired_count_)
|
| + --*acquired_count_;
|
| + if (!acquired_count_ || *acquired_count_ == 0)
|
| + lock_.Release();
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace scheduler
|
| } // namespace blink
|
|
|