Chromium Code Reviews| 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..9263754c83218e43fe8d0d563c44e7f91e2cfedb 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 |
| @@ -169,6 +169,7 @@ TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} |
| void TaskQueueImpl::UnregisterTaskQueue() { |
| base::AutoLock lock(any_thread_lock_); |
| + base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_); |
| if (main_thread_only().time_domain) |
| main_thread_only().time_domain->UnregisterQueue(this); |
| if (!any_thread().task_queue_manager) |
| @@ -180,7 +181,7 @@ void TaskQueueImpl::UnregisterTaskQueue() { |
| any_thread().task_queue_manager = nullptr; |
| main_thread_only().task_queue_manager = nullptr; |
| main_thread_only().delayed_incoming_queue = std::priority_queue<Task>(); |
| - any_thread().immediate_incoming_queue.clear(); |
| + immediate_incoming_queue().clear(); |
| main_thread_only().immediate_work_queue.reset(); |
| main_thread_only().delayed_work_queue.reset(); |
| } |
| @@ -286,7 +287,7 @@ void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( |
| this, {delayed_run_time, pending_task.sequence_num}, now); |
| } |
| - TraceQueueSize(false); |
| + TraceQueueSize(); |
| } |
| void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { |
| @@ -321,7 +322,7 @@ void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { |
| PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task), |
| time_domain_now); |
| } |
| - TraceQueueSize(false); |
| + TraceQueueSize(); |
| } |
| void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( |
| @@ -332,7 +333,12 @@ void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( |
| bool nestable) { |
| // If the |immediate_incoming_queue| is empty we need a DoWork posted to make |
| // it run. |
| - if (any_thread().immediate_incoming_queue.empty()) { |
| + bool is_immediate_incoming_queue_empty; |
| + { |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + is_immediate_incoming_queue_empty = immediate_incoming_queue().empty(); |
| + } |
| + if (is_immediate_incoming_queue_empty) { |
| // However there's no point posting a DoWork for a blocked queue. NB we can |
| // only tell if it's disabled from the main thread. |
| bool queue_is_blocked = |
| @@ -342,12 +348,17 @@ void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( |
| this, sequence_number, queue_is_blocked); |
| any_thread().time_domain->OnQueueHasImmediateWork(this); |
| } |
| - any_thread().immediate_incoming_queue.emplace_back( |
| - posted_from, task, desired_run_time, sequence_number, nestable, |
| - sequence_number); |
| - any_thread().task_queue_manager->DidQueueTask( |
| - any_thread().immediate_incoming_queue.back()); |
| - TraceQueueSize(true); |
| + |
| + Task* queued_task; |
| + { |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
|
alex clarke (OOO till 29th)
2017/03/30 13:23:46
Can we avoid locking this twice?
altimin
2017/03/30 14:04:36
Done.
|
| + immediate_incoming_queue().emplace_back(posted_from, task, desired_run_time, |
| + sequence_number, nestable, |
| + sequence_number); |
| + queued_task = &immediate_incoming_queue().back(); |
| + } |
| + any_thread().task_queue_manager->DidQueueTask(*queued_task); |
| + TraceQueueSize(); |
| } |
| void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { |
| @@ -359,8 +370,9 @@ void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { |
| WTF::Deque<TaskQueueImpl::Task> TaskQueueImpl::TakeImmediateIncomingQueue() { |
| base::AutoLock lock(any_thread_lock_); |
| + base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_); |
| WTF::Deque<TaskQueueImpl::Task> queue; |
| - queue.swap(any_thread().immediate_incoming_queue); |
| + queue.swap(immediate_incoming_queue()); |
| return queue; |
| } |
| @@ -371,8 +383,8 @@ bool TaskQueueImpl::IsEmpty() const { |
| return false; |
| } |
| - base::AutoLock lock(any_thread_lock_); |
| - return any_thread().immediate_incoming_queue.empty(); |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + return immediate_incoming_queue().empty(); |
| } |
| size_t TaskQueueImpl::GetNumberOfPendingTasks() const { |
| @@ -381,8 +393,8 @@ 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_); |
| - task_count += any_thread().immediate_incoming_queue.size(); |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + task_count += immediate_incoming_queue().size(); |
| return task_count; |
| } |
| @@ -402,8 +414,8 @@ bool TaskQueueImpl::HasPendingImmediateWork() const { |
| } |
| // Finally tasks on |immediate_incoming_queue| count as immediate work. |
| - base::AutoLock lock(any_thread_lock_); |
| - return !any_thread().immediate_incoming_queue.empty(); |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + return !immediate_incoming_queue().empty(); |
| } |
| base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() { |
| @@ -443,7 +455,7 @@ TaskQueueImpl::WakeUpForDelayedWork(LazyNow* lazy_now) { |
| return base::nullopt; |
| } |
| -void TaskQueueImpl::TraceQueueSize(bool is_locked) const { |
| +void TaskQueueImpl::TraceQueueSize() const { |
| bool is_tracing; |
| TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, |
| &is_tracing); |
| @@ -455,17 +467,12 @@ void TaskQueueImpl::TraceQueueSize(bool is_locked) const { |
| if (base::PlatformThread::CurrentId() != thread_id_) |
| return; |
| - if (!is_locked) |
| - any_thread_lock_.Acquire(); |
| - else |
| - any_thread_lock_.AssertAcquired(); |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(), |
| - any_thread().immediate_incoming_queue.size() + |
| + immediate_incoming_queue().size() + |
| main_thread_only().immediate_work_queue->Size() + |
| main_thread_only().delayed_work_queue->Size() + |
| main_thread_only().delayed_incoming_queue.size()); |
| - if (!is_locked) |
| - any_thread_lock_.Release(); |
| } |
| const char* TaskQueueImpl::GetName() const { |
| @@ -491,6 +498,7 @@ TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const { |
| void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { |
| base::AutoLock lock(any_thread_lock_); |
| + base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_); |
| state->BeginDictionary(); |
| state->SetString("name", GetName()); |
| state->SetString( |
| @@ -504,7 +512,7 @@ void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { |
| TRACE_EVENT_CATEGORY_GROUP_ENABLED( |
| disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled); |
| state->SetInteger("immediate_incoming_queue_size", |
| - any_thread().immediate_incoming_queue.size()); |
| + immediate_incoming_queue().size()); |
| state->SetInteger("delayed_incoming_queue_size", |
| main_thread_only().delayed_incoming_queue.size()); |
| state->SetInteger("immediate_work_queue_size", |
| @@ -522,7 +530,7 @@ void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { |
| state->SetInteger("current_fence", main_thread_only().current_fence); |
| if (verbose_tracing_enabled) { |
| state->BeginArray("immediate_incoming_queue"); |
| - QueueAsValueInto(any_thread().immediate_incoming_queue, state); |
| + QueueAsValueInto(immediate_incoming_queue(), state); |
| state->EndArray(); |
| state->BeginArray("delayed_work_queue"); |
| main_thread_only().delayed_work_queue->AsValueInto(state); |
| @@ -629,11 +637,10 @@ void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) { |
| if (!task_unblocked && previous_fence && |
| previous_fence < main_thread_only().current_fence) { |
| - base::AutoLock lock(any_thread_lock_); |
| - if (!any_thread().immediate_incoming_queue.empty() && |
| - any_thread().immediate_incoming_queue.front().enqueue_order() > |
| - previous_fence && |
| - any_thread().immediate_incoming_queue.front().enqueue_order() < |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + if (!immediate_incoming_queue().empty() && |
| + immediate_incoming_queue().front().enqueue_order() > previous_fence && |
| + immediate_incoming_queue().front().enqueue_order() < |
| main_thread_only().current_fence) { |
| task_unblocked = true; |
| } |
| @@ -656,10 +663,9 @@ void TaskQueueImpl::RemoveFence() { |
| task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence(); |
| if (!task_unblocked && previous_fence) { |
| - base::AutoLock lock(any_thread_lock_); |
| - if (!any_thread().immediate_incoming_queue.empty() && |
| - any_thread().immediate_incoming_queue.front().enqueue_order() > |
| - previous_fence) { |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + if (!immediate_incoming_queue().empty() && |
| + immediate_incoming_queue().front().enqueue_order() > previous_fence) { |
| task_unblocked = true; |
| } |
| } |
| @@ -679,11 +685,11 @@ bool TaskQueueImpl::BlockedByFence() const { |
| return false; |
| } |
| - base::AutoLock lock(any_thread_lock_); |
| - if (any_thread().immediate_incoming_queue.empty()) |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + if (immediate_incoming_queue().empty()) |
| return true; |
| - return any_thread().immediate_incoming_queue.front().enqueue_order() > |
| + return immediate_incoming_queue().front().enqueue_order() > |
| main_thread_only().current_fence; |
| } |
| @@ -812,8 +818,8 @@ 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_); |
| - immediate_queues_empty = any_thread().immediate_incoming_queue.empty(); |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + immediate_queues_empty = immediate_incoming_queue().empty(); |
| } |
| // Avoid holding the lock while we fire the notification. |
| if (!immediate_queues_empty) |
| @@ -879,8 +885,8 @@ void TaskQueueImpl::SweepCanceledDelayedTasks(base::TimeTicks now) { |
| void TaskQueueImpl::PushImmediateIncomingTaskForTest( |
| TaskQueueImpl::Task&& task) { |
| - base::AutoLock lock(any_thread_lock_); |
| - any_thread().immediate_incoming_queue.push_back(std::move(task)); |
| + base::AutoLock lock(immediate_incoming_queue_lock_); |
| + immediate_incoming_queue().push_back(std::move(task)); |
| } |
| } // namespace internal |