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

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

Issue 2540663002: Add the concept of QueueEnabledVoters to blink scheduler TaskQueue (Closed)
Patch Set: Fix test crashes and address feedback. Created 4 years, 1 month 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
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..8ad3792e25302071d35e9993538318000014bf8b 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) {}
@@ -185,7 +187,6 @@ bool TaskQueueImpl::RunsTasksOnCurrentThread() const {
return base::PlatformThread::CurrentId() == thread_id_;
}
-
bool TaskQueueImpl::PostDelayedTask(const tracked_objects::Location& from_here,
const base::Closure& task,
base::TimeDelta delay) {
@@ -332,7 +333,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 +345,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 +488,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 +622,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 +647,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 +742,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);
+}
+
+void TaskQueueImpl::QueueEnabledVoterImpl::SetQueueEnabled(bool enabled) {
+ if (enabled_ == enabled)
+ return;
+
+ task_queue_->OnQueueEnabledVoteChanged(enabled);
+ enabled_ = enabled;
+}
+
+void TaskQueueImpl::RemoveQueueEnabledVoter(
+ const QueueEnabledVoterImpl* voter) {
+ // Bail out if we're being called from TaskQueueImpl::UnregisterTaskQueue.
+ if (!main_thread_only().time_domain)
+ return;
+
+ 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::OnQueueEnabledVoteChanged(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::CreateQueueEnabledVoter() {
+ main_thread_only().voter_refcount++;
+ main_thread_only().is_enabled_refcount++;
+ return base::MakeUnique<QueueEnabledVoterImpl>(this);
+}
+
} // namespace internal
} // namespace scheduler
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698