Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Unified Diff: third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc

Issue 2777063010: [scheduler] Make any thread lock in TaskQueueImpl reentrable. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698