diff options
author | skyostil <skyostil@chromium.org> | 2015-07-16 07:39:26 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-16 14:40:10 +0000 |
commit | 2a96102e57a45f9c87187fb2b4f35c3cdba6153a (patch) | |
tree | 1f954fb30f9730d86974266671864715d8046b01 /components | |
parent | 2758adfdb7d5e8274152f443ee924163812e1c61 (diff) | |
download | chromium_src-2a96102e57a45f9c87187fb2b4f35c3cdba6153a.zip chromium_src-2a96102e57a45f9c87187fb2b4f35c3cdba6153a.tar.gz chromium_src-2a96102e57a45f9c87187fb2b4f35c3cdba6153a.tar.bz2 |
Implement PostDelayedTaskAt for guaranteed timer ordering
This patch implements a new method for posting delayed tasks:
PostDelayedTaskAt(). In contrast to PostDelayedTask(), this API accepts
the desired run time as an absolute time stamp instead of a delta from
the current time. This makes it possible for Blink to post several
aligned timers to the same desired run time and have the timers execute
in their posted order.
BUG=508279
Review URL: https://codereview.chromium.org/1223163006
Cr-Commit-Position: refs/heads/master@{#339024}
Diffstat (limited to 'components')
27 files changed, 321 insertions, 113 deletions
diff --git a/components/scheduler/child/child_scheduler.h b/components/scheduler/child/child_scheduler.h index 8fd5359..14f9efb 100644 --- a/components/scheduler/child/child_scheduler.h +++ b/components/scheduler/child/child_scheduler.h @@ -7,6 +7,7 @@ #include "base/message_loop/message_loop.h" #include "components/scheduler/child/single_thread_idle_task_runner.h" +#include "components/scheduler/child/task_queue.h" #include "components/scheduler/scheduler_export.h" namespace base { @@ -20,7 +21,7 @@ class SCHEDULER_EXPORT ChildScheduler { virtual ~ChildScheduler() {} // Returns the default task runner. - virtual scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() = 0; + virtual scoped_refptr<TaskQueue> DefaultTaskRunner() = 0; // Returns the idle task runner. Tasks posted to this runner may be reordered // relative to other task types and may be starved for an arbitrarily long diff --git a/components/scheduler/child/idle_helper.cc b/components/scheduler/child/idle_helper.cc index 756fc1b8..e3adeb0 100644 --- a/components/scheduler/child/idle_helper.cc +++ b/components/scheduler/child/idle_helper.cc @@ -8,6 +8,7 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "components/scheduler/child/scheduler_helper.h" +#include "components/scheduler/child/task_queue.h" namespace scheduler { diff --git a/components/scheduler/child/idle_helper_unittest.cc b/components/scheduler/child/idle_helper_unittest.cc index 20ae1b5..5c01ab8 100644 --- a/components/scheduler/child/idle_helper_unittest.cc +++ b/components/scheduler/child/idle_helper_unittest.cc @@ -10,6 +10,7 @@ #include "components/scheduler/child/nestable_task_runner_for_test.h" #include "components/scheduler/child/scheduler_helper.h" #include "components/scheduler/child/scheduler_message_loop_delegate.h" +#include "components/scheduler/child/task_queue.h" #include "components/scheduler/child/task_queue_manager.h" #include "components/scheduler/child/test_time_source.h" #include "testing/gmock/include/gmock/gmock.h" diff --git a/components/scheduler/child/null_task_queue.cc b/components/scheduler/child/null_task_queue.cc new file mode 100644 index 0000000..ef5bab5 --- /dev/null +++ b/components/scheduler/child/null_task_queue.cc @@ -0,0 +1,41 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/scheduler/child/null_task_queue.h" + +namespace scheduler { + +NullTaskQueue::NullTaskQueue( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : task_runner_(task_runner) {} + +NullTaskQueue::~NullTaskQueue() {} + +bool NullTaskQueue::RunsTasksOnCurrentThread() const { + return task_runner_->RunsTasksOnCurrentThread(); +} + +bool NullTaskQueue::PostDelayedTask(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) { + return task_runner_->PostDelayedTask(from_here, task, delay); +} + +bool NullTaskQueue::PostNonNestableDelayedTask( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) { + return task_runner_->PostNonNestableDelayedTask(from_here, task, delay); +} +bool NullTaskQueue::PostDelayedTaskAt( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeTicks desired_run_time) { + // Note: this loses the guarantee of monotonicity but we can't do any better + // with base::TaskRunner. + return task_runner_->PostDelayedTask( + from_here, task, desired_run_time - base::TimeTicks::Now()); +} + +} // namespace scheduler diff --git a/components/scheduler/child/null_task_queue.h b/components/scheduler/child/null_task_queue.h new file mode 100644 index 0000000..7c4e5d8 --- /dev/null +++ b/components/scheduler/child/null_task_queue.h @@ -0,0 +1,39 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SCHEDULER_NULL_CHILD_TASK_QUEUE_H_ +#define COMPONENTS_SCHEDULER_NULL_CHILD_TASK_QUEUE_H_ + +#include "components/scheduler/child/task_queue.h" +#include "components/scheduler/scheduler_export.h" + +namespace scheduler { + +class SCHEDULER_EXPORT NullTaskQueue : public TaskQueue { + public: + NullTaskQueue(scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // TaskQueue implementation + bool RunsTasksOnCurrentThread() const override; + bool PostDelayedTask(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) override; + bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) override; + bool PostDelayedTaskAt(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeTicks desired_run_time) override; + + protected: + ~NullTaskQueue() override; + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + DISALLOW_COPY_AND_ASSIGN(NullTaskQueue); +}; + +} // namespace scheduler + +#endif // COMPONENTS_SCHEDULER_CHILD_NULL_TASK_QUEUE_H_ diff --git a/components/scheduler/child/null_worker_scheduler.cc b/components/scheduler/child/null_worker_scheduler.cc index 4abfb0e..3f0a7cd 100644 --- a/components/scheduler/child/null_worker_scheduler.cc +++ b/components/scheduler/child/null_worker_scheduler.cc @@ -8,19 +8,18 @@ #include "base/message_loop/message_loop.h" #include "base/thread_task_runner_handle.h" #include "components/scheduler/child/null_idle_task_runner.h" +#include "components/scheduler/child/null_task_queue.h" namespace scheduler { NullWorkerScheduler::NullWorkerScheduler() - : task_runner_(base::ThreadTaskRunnerHandle::Get()), - idle_task_runner_(new NullIdleTaskRunner()) { -} + : task_runner_(new NullTaskQueue(base::ThreadTaskRunnerHandle::Get())), + idle_task_runner_(new NullIdleTaskRunner()) {} NullWorkerScheduler::~NullWorkerScheduler() { } -scoped_refptr<base::SingleThreadTaskRunner> -NullWorkerScheduler::DefaultTaskRunner() { +scoped_refptr<TaskQueue> NullWorkerScheduler::DefaultTaskRunner() { return task_runner_; } diff --git a/components/scheduler/child/null_worker_scheduler.h b/components/scheduler/child/null_worker_scheduler.h index 535fa08..4e0daae 100644 --- a/components/scheduler/child/null_worker_scheduler.h +++ b/components/scheduler/child/null_worker_scheduler.h @@ -14,7 +14,7 @@ class NullWorkerScheduler : public WorkerScheduler { NullWorkerScheduler(); ~NullWorkerScheduler() override; - scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; + scoped_refptr<TaskQueue> DefaultTaskRunner() override; scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override; void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override; @@ -26,7 +26,7 @@ class NullWorkerScheduler : public WorkerScheduler { void Shutdown() override; private: - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + scoped_refptr<TaskQueue> task_runner_; scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; DISALLOW_COPY_AND_ASSIGN(NullWorkerScheduler); diff --git a/components/scheduler/child/scheduler_helper.cc b/components/scheduler/child/scheduler_helper.cc index 0e13c76..eb93a08 100644 --- a/components/scheduler/child/scheduler_helper.cc +++ b/components/scheduler/child/scheduler_helper.cc @@ -8,6 +8,7 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "components/scheduler/child/nestable_single_thread_task_runner.h" +#include "components/scheduler/child/task_queue.h" namespace scheduler { @@ -74,8 +75,7 @@ void SchedulerHelper::Shutdown() { task_queue_manager_.reset(); } -scoped_refptr<base::SingleThreadTaskRunner> -SchedulerHelper::DefaultTaskRunner() { +scoped_refptr<TaskQueue> SchedulerHelper::DefaultTaskRunner() { CheckOnValidThread(); return default_task_runner_; } @@ -110,7 +110,7 @@ base::TimeTicks SchedulerHelper::Now() const { return time_source_->NowTicks(); } -scoped_refptr<base::SingleThreadTaskRunner> SchedulerHelper::TaskRunnerForQueue( +scoped_refptr<TaskQueue> SchedulerHelper::TaskRunnerForQueue( size_t queue_index) const { CheckOnValidThread(); return task_queue_manager_->TaskRunnerForQueue(queue_index); diff --git a/components/scheduler/child/scheduler_helper.h b/components/scheduler/child/scheduler_helper.h index 3c439c7..5c0c973 100644 --- a/components/scheduler/child/scheduler_helper.h +++ b/components/scheduler/child/scheduler_helper.h @@ -32,7 +32,7 @@ class SCHEDULER_EXPORT SchedulerHelper { ~SchedulerHelper(); // Returns the default task runner. - scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner(); + scoped_refptr<TaskQueue> DefaultTaskRunner(); // Returns the control task runner. Tasks posted to this runner are executed // with the highest priority. Care must be taken to avoid starvation of other @@ -76,8 +76,7 @@ class SCHEDULER_EXPORT SchedulerHelper { // Accessor methods. base::TimeTicks Now() const; - scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerForQueue( - size_t queue_index) const; + scoped_refptr<TaskQueue> TaskRunnerForQueue(size_t queue_index) const; base::TimeTicks NextPendingDelayedTaskRunTime() const; void SetQueueName(size_t queue_index, const char* name); bool IsQueueEmpty(size_t queue_index) const; @@ -112,7 +111,7 @@ class SCHEDULER_EXPORT SchedulerHelper { scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> control_after_wakeup_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; + scoped_refptr<TaskQueue> default_task_runner_; scoped_ptr<base::TickClock> time_source_; diff --git a/components/scheduler/child/scheduler_helper_unittest.cc b/components/scheduler/child/scheduler_helper_unittest.cc index 85c811a..0e0dd71 100644 --- a/components/scheduler/child/scheduler_helper_unittest.cc +++ b/components/scheduler/child/scheduler_helper_unittest.cc @@ -9,6 +9,7 @@ #include "cc/test/ordered_simple_task_runner.h" #include "components/scheduler/child/nestable_task_runner_for_test.h" #include "components/scheduler/child/scheduler_message_loop_delegate.h" +#include "components/scheduler/child/task_queue.h" #include "components/scheduler/child/test_time_source.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/components/scheduler/child/task_queue.h b/components/scheduler/child/task_queue.h new file mode 100644 index 0000000..a574c61 --- /dev/null +++ b/components/scheduler/child/task_queue.h @@ -0,0 +1,31 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_H_ +#define COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_H_ + +#include "base/single_thread_task_runner.h" +#include "components/scheduler/scheduler_export.h" + +namespace scheduler { + +class SCHEDULER_EXPORT TaskQueue : public base::SingleThreadTaskRunner { + public: + TaskQueue() {} + + // Post a delayed task at an absolute desired run time instead of a time + // delta from the current time. + virtual bool PostDelayedTaskAt(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeTicks desired_run_time) = 0; + + protected: + ~TaskQueue() override {} + + DISALLOW_COPY_AND_ASSIGN(TaskQueue); +}; + +} // namespace scheduler + +#endif // COMPONENTS_SCHEDULER_CHILD_TASK_QUEUE_H_ diff --git a/components/scheduler/child/task_queue_manager.cc b/components/scheduler/child/task_queue_manager.cc index 620ede5..606fe7f 100644 --- a/components/scheduler/child/task_queue_manager.cc +++ b/components/scheduler/child/task_queue_manager.cc @@ -12,6 +12,7 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "components/scheduler/child/nestable_single_thread_task_runner.h" +#include "components/scheduler/child/task_queue.h" #include "components/scheduler/child/task_queue_selector.h" namespace { @@ -44,13 +45,13 @@ class LazyNow { base::TimeTicks now_; }; -class TaskQueue : public base::SingleThreadTaskRunner { +class TaskQueueImpl : public TaskQueue { public: - TaskQueue(TaskQueueManager* task_queue_manager, - const char* disabled_by_default_tracing_category, - const char* disabled_by_default_verbose_tracing_category); + TaskQueueImpl(TaskQueueManager* task_queue_manager, + const char* disabled_by_default_tracing_category, + const char* disabled_by_default_verbose_tracing_category); - // base::SingleThreadTaskRunner implementation. + // TaskQueue :implementation. bool RunsTasksOnCurrentThread() const override; bool PostDelayedTask(const tracked_objects::Location& from_here, const base::Closure& task, @@ -63,6 +64,9 @@ class TaskQueue : public base::SingleThreadTaskRunner { base::TimeDelta delay) override { return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); } + bool PostDelayedTaskAt(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeTicks desired_run_time) override; TaskQueueManager::QueueState GetQueueState() const; @@ -101,12 +105,17 @@ class TaskQueue : public base::SingleThreadTaskRunner { NON_NESTABLE, }; - ~TaskQueue() override; + ~TaskQueueImpl() override; bool PostDelayedTaskImpl(const tracked_objects::Location& from_here, const base::Closure& task, base::TimeDelta delay, TaskType task_type); + bool PostDelayedTaskLocked(LazyNow* lazy_now, + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeTicks desired_run_time, + TaskType task_type); // Delayed task posted to the underlying run loop, which locks |lock_| and // calls MoveReadyDelayedTasksToIncomingQueueLocked to process dealyed tasks @@ -149,6 +158,11 @@ class TaskQueue : public base::SingleThreadTaskRunner { const char* name_; const char* disabled_by_default_tracing_category_; const char* disabled_by_default_verbose_tracing_category_; + + // Queue-local task sequence number for maintaining the order of delayed + // tasks which are posted for the exact same time. Note that this will be + // replaced by the global sequence number when the delay has elapsed. + int delayed_task_sequence_number_; base::DelayedTaskQueue delayed_task_queue_; std::set<base::TimeTicks> in_flight_kick_delayed_tasks_; @@ -156,12 +170,13 @@ class TaskQueue : public base::SingleThreadTaskRunner { base::TaskQueue work_queue_; TaskQueueManager::WakeupPolicy wakeup_policy_; - DISALLOW_COPY_AND_ASSIGN(TaskQueue); + DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl); }; -TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager, - const char* disabled_by_default_tracing_category, - const char* disabled_by_default_verbose_tracing_category) +TaskQueueImpl::TaskQueueImpl( + TaskQueueManager* task_queue_manager, + const char* disabled_by_default_tracing_category, + const char* disabled_by_default_verbose_tracing_category) : thread_id_(base::PlatformThread::CurrentId()), task_queue_manager_(task_queue_manager), pump_policy_(TaskQueueManager::PumpPolicy::AUTO), @@ -170,13 +185,12 @@ TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager, disabled_by_default_tracing_category), disabled_by_default_verbose_tracing_category_( disabled_by_default_verbose_tracing_category), - wakeup_policy_(TaskQueueManager::WakeupPolicy::CAN_WAKE_OTHER_QUEUES) { -} + delayed_task_sequence_number_(0), + wakeup_policy_(TaskQueueManager::WakeupPolicy::CAN_WAKE_OTHER_QUEUES) {} -TaskQueue::~TaskQueue() { -} +TaskQueueImpl::~TaskQueueImpl() {} -void TaskQueue::WillDeleteTaskQueueManager() { +void TaskQueueImpl::WillDeleteTaskQueueManager() { base::AutoLock lock(lock_); task_queue_manager_ = nullptr; delayed_task_queue_ = base::DelayedTaskQueue(); @@ -184,40 +198,67 @@ void TaskQueue::WillDeleteTaskQueueManager() { work_queue_ = base::TaskQueue(); } -bool TaskQueue::RunsTasksOnCurrentThread() const { +bool TaskQueueImpl::RunsTasksOnCurrentThread() const { base::AutoLock lock(lock_); return base::PlatformThread::CurrentId() == thread_id_; } -bool TaskQueue::PostDelayedTaskImpl(const tracked_objects::Location& from_here, - const base::Closure& task, - base::TimeDelta delay, - TaskType task_type) { +bool TaskQueueImpl::PostDelayedTaskAt( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeTicks desired_run_time) { + base::AutoLock lock(lock_); + if (!task_queue_manager_) + return false; + LazyNow lazy_now(task_queue_manager_); + return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, + TaskType::NORMAL); +} + +bool TaskQueueImpl::PostDelayedTaskImpl( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay, + TaskType task_type) { base::AutoLock lock(lock_); if (!task_queue_manager_) return false; + LazyNow lazy_now(task_queue_manager_); + base::TimeTicks desired_run_time; + if (delay > base::TimeDelta()) + desired_run_time = lazy_now.Now() + delay; + return PostDelayedTaskLocked(&lazy_now, from_here, task, desired_run_time, + task_type); +} + +bool TaskQueueImpl::PostDelayedTaskLocked( + LazyNow* lazy_now, + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeTicks desired_run_time, + TaskType task_type) { + lock_.AssertAcquired(); + DCHECK(task_queue_manager_); base::PendingTask pending_task(from_here, task, base::TimeTicks(), task_type != TaskType::NON_NESTABLE); task_queue_manager_->DidQueueTask(pending_task); - if (delay > base::TimeDelta()) { - base::TimeTicks now = task_queue_manager_->Now(); - pending_task.delayed_run_time = now + delay; + if (!desired_run_time.is_null()) { + pending_task.delayed_run_time = std::max(lazy_now->Now(), desired_run_time); + pending_task.sequence_num = delayed_task_sequence_number_++; delayed_task_queue_.push(pending_task); TraceQueueSize(true); // If we changed the topmost task, then it is time to reschedule. - if (delayed_task_queue_.top().task.Equals(pending_task.task)) { - LazyNow lazy_now(now); - ScheduleDelayedWorkLocked(&lazy_now); - } + if (delayed_task_queue_.top().task.Equals(pending_task.task)) + ScheduleDelayedWorkLocked(lazy_now); return true; } EnqueueTaskLocked(pending_task); return true; } -void TaskQueue::MoveReadyDelayedTasksToIncomingQueue() { +void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue() { DCHECK(main_thread_checker_.CalledOnValidThread()); base::AutoLock lock(lock_); if (!task_queue_manager_) @@ -227,7 +268,8 @@ void TaskQueue::MoveReadyDelayedTasksToIncomingQueue() { MoveReadyDelayedTasksToIncomingQueueLocked(&lazy_now); } -void TaskQueue::MoveReadyDelayedTasksToIncomingQueueLocked(LazyNow* lazy_now) { +void TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueueLocked( + LazyNow* lazy_now) { lock_.AssertAcquired(); // Enqueue all delayed tasks that should be running now. while (!delayed_task_queue_.empty() && @@ -241,12 +283,12 @@ void TaskQueue::MoveReadyDelayedTasksToIncomingQueueLocked(LazyNow* lazy_now) { ScheduleDelayedWorkLocked(lazy_now); } -void TaskQueue::ScheduleDelayedWorkLocked(LazyNow* lazy_now) { +void TaskQueueImpl::ScheduleDelayedWorkLocked(LazyNow* lazy_now) { lock_.AssertAcquired(); // Any remaining tasks are in the future, so queue a task to kick them. if (!delayed_task_queue_.empty()) { base::TimeTicks next_run_time = delayed_task_queue_.top().delayed_run_time; - DCHECK_GT(next_run_time, lazy_now->Now()); + DCHECK_GE(next_run_time, lazy_now->Now()); // Make sure we don't have more than one // MoveReadyDelayedTasksToIncomingQueue posted for a particular scheduled // run time (note it's fine to have multiple ones in flight for distinct @@ -257,12 +299,13 @@ void TaskQueue::ScheduleDelayedWorkLocked(LazyNow* lazy_now) { base::TimeDelta delay = next_run_time - lazy_now->Now(); task_queue_manager_->PostDelayedTask( FROM_HERE, - Bind(&TaskQueue::MoveReadyDelayedTasksToIncomingQueue, this), delay); + Bind(&TaskQueueImpl::MoveReadyDelayedTasksToIncomingQueue, this), + delay); } } } -TaskQueueManager::QueueState TaskQueue::GetQueueState() const { +TaskQueueManager::QueueState TaskQueueImpl::GetQueueState() const { DCHECK(main_thread_checker_.CalledOnValidThread()); if (!work_queue_.empty()) return TaskQueueManager::QueueState::HAS_WORK; @@ -277,7 +320,7 @@ TaskQueueManager::QueueState TaskQueue::GetQueueState() const { } } -bool TaskQueue::TaskIsOlderThanQueuedTasks(const base::PendingTask* task) { +bool TaskQueueImpl::TaskIsOlderThanQueuedTasks(const base::PendingTask* task) { lock_.AssertAcquired(); // A null task is passed when UpdateQueue is called before any task is run. // In this case we don't want to pump an after_wakeup queue, so return true @@ -299,7 +342,7 @@ bool TaskQueue::TaskIsOlderThanQueuedTasks(const base::PendingTask* task) { return oldest_queued_task < *task; } -bool TaskQueue::ShouldAutoPumpQueueLocked( +bool TaskQueueImpl::ShouldAutoPumpQueueLocked( bool should_trigger_wakeup, const base::PendingTask* previous_task) { lock_.AssertAcquired(); @@ -313,7 +356,7 @@ bool TaskQueue::ShouldAutoPumpQueueLocked( return true; } -bool TaskQueue::NextPendingDelayedTaskRunTime( +bool TaskQueueImpl::NextPendingDelayedTaskRunTime( base::TimeTicks* next_pending_delayed_task) { base::AutoLock lock(lock_); if (delayed_task_queue_.empty()) @@ -322,9 +365,9 @@ bool TaskQueue::NextPendingDelayedTaskRunTime( return true; } -bool TaskQueue::UpdateWorkQueue(LazyNow* lazy_now, - bool should_trigger_wakeup, - const base::PendingTask* previous_task) { +bool TaskQueueImpl::UpdateWorkQueue(LazyNow* lazy_now, + bool should_trigger_wakeup, + const base::PendingTask* previous_task) { if (!work_queue_.empty()) return true; @@ -339,14 +382,14 @@ bool TaskQueue::UpdateWorkQueue(LazyNow* lazy_now, } } -base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { +base::PendingTask TaskQueueImpl::TakeTaskFromWorkQueue() { base::PendingTask pending_task = work_queue_.front(); work_queue_.pop(); TraceQueueSize(false); return pending_task; } -void TaskQueue::TraceQueueSize(bool is_locked) const { +void TaskQueueImpl::TraceQueueSize(bool is_locked) const { bool is_tracing; TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, &is_tracing); @@ -363,7 +406,7 @@ void TaskQueue::TraceQueueSize(bool is_locked) const { lock_.Release(); } -void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { +void TaskQueueImpl::EnqueueTaskLocked(const base::PendingTask& pending_task) { lock_.AssertAcquired(); if (!task_queue_manager_) return; @@ -382,7 +425,7 @@ void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { TraceQueueSize(true); } -void TaskQueue::SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy) { +void TaskQueueImpl::SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy) { base::AutoLock lock(lock_); if (pump_policy == TaskQueueManager::PumpPolicy::AUTO && pump_policy_ != TaskQueueManager::PumpPolicy::AUTO) { @@ -391,7 +434,7 @@ void TaskQueue::SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy) { pump_policy_ = pump_policy; } -void TaskQueue::PumpQueueLocked() { +void TaskQueueImpl::PumpQueueLocked() { lock_.AssertAcquired(); if (task_queue_manager_) { LazyNow lazy_now(task_queue_manager_); @@ -405,12 +448,12 @@ void TaskQueue::PumpQueueLocked() { task_queue_manager_->MaybePostDoWorkOnMainRunner(); } -void TaskQueue::PumpQueue() { +void TaskQueueImpl::PumpQueue() { base::AutoLock lock(lock_); PumpQueueLocked(); } -void TaskQueue::AsValueInto(base::trace_event::TracedValue* state) const { +void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { base::AutoLock lock(lock_); state->BeginDictionary(); if (name_) @@ -440,8 +483,8 @@ void TaskQueue::AsValueInto(base::trace_event::TracedValue* state) const { } // static -void TaskQueue::QueueAsValueInto(const base::TaskQueue& queue, - base::trace_event::TracedValue* state) { +void TaskQueueImpl::QueueAsValueInto(const base::TaskQueue& queue, + base::trace_event::TracedValue* state) { base::TaskQueue queue_copy(queue); while (!queue_copy.empty()) { TaskAsValueInto(queue_copy.front(), state); @@ -450,8 +493,8 @@ void TaskQueue::QueueAsValueInto(const base::TaskQueue& queue, } // static -void TaskQueue::QueueAsValueInto(const base::DelayedTaskQueue& queue, - base::trace_event::TracedValue* state) { +void TaskQueueImpl::QueueAsValueInto(const base::DelayedTaskQueue& queue, + base::trace_event::TracedValue* state) { base::DelayedTaskQueue queue_copy(queue); while (!queue_copy.empty()) { TaskAsValueInto(queue_copy.top(), state); @@ -460,8 +503,8 @@ void TaskQueue::QueueAsValueInto(const base::DelayedTaskQueue& queue, } // static -void TaskQueue::TaskAsValueInto(const base::PendingTask& task, - base::trace_event::TracedValue* state) { +void TaskQueueImpl::TaskAsValueInto(const base::PendingTask& task, + base::trace_event::TracedValue* state) { state->BeginDictionary(); state->SetString("posted_from", task.posted_from.ToString()); state->SetInteger("sequence_num", task.sequence_num); @@ -498,10 +541,10 @@ TaskQueueManager::TaskQueueManager( "TaskQueueManager", this); for (size_t i = 0; i < task_queue_count; i++) { - scoped_refptr<internal::TaskQueue> queue(make_scoped_refptr( - new internal::TaskQueue(this, - disabled_by_default_tracing_category, - disabled_by_default_verbose_tracing_category))); + scoped_refptr<internal::TaskQueueImpl> queue( + make_scoped_refptr(new internal::TaskQueueImpl( + this, disabled_by_default_tracing_category, + disabled_by_default_verbose_tracing_category))); queues_.push_back(queue); } @@ -525,13 +568,13 @@ TaskQueueManager::~TaskQueueManager() { selector_->SetTaskQueueSelectorObserver(nullptr); } -internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const { +internal::TaskQueueImpl* TaskQueueManager::Queue(size_t queue_index) const { DCHECK_LT(queue_index, queues_.size()); return queues_[queue_index].get(); } -scoped_refptr<base::SingleThreadTaskRunner> -TaskQueueManager::TaskRunnerForQueue(size_t queue_index) const { +scoped_refptr<TaskQueue> TaskQueueManager::TaskRunnerForQueue( + size_t queue_index) const { return Queue(queue_index); } @@ -570,20 +613,20 @@ base::TimeTicks TaskQueueManager::NextPendingDelayedTaskRunTime() { void TaskQueueManager::SetPumpPolicy(size_t queue_index, PumpPolicy pump_policy) { DCHECK(main_thread_checker_.CalledOnValidThread()); - internal::TaskQueue* queue = Queue(queue_index); + internal::TaskQueueImpl* queue = Queue(queue_index); queue->SetPumpPolicy(pump_policy); } void TaskQueueManager::SetWakeupPolicy(size_t queue_index, WakeupPolicy wakeup_policy) { DCHECK(main_thread_checker_.CalledOnValidThread()); - internal::TaskQueue* queue = Queue(queue_index); + internal::TaskQueueImpl* queue = Queue(queue_index); queue->set_wakeup_policy(wakeup_policy); } void TaskQueueManager::PumpQueue(size_t queue_index) { DCHECK(main_thread_checker_.CalledOnValidThread()); - internal::TaskQueue* queue = Queue(queue_index); + internal::TaskQueueImpl* queue = Queue(queue_index); queue->PumpQueue(); } @@ -673,7 +716,7 @@ bool TaskQueueManager::ProcessTaskFromWorkQueue( base::PendingTask* previous_task) { DCHECK(main_thread_checker_.CalledOnValidThread()); scoped_refptr<DeletionSentinel> protect(deletion_sentinel_); - internal::TaskQueue* queue = Queue(queue_index); + internal::TaskQueueImpl* queue = Queue(queue_index); base::PendingTask pending_task = queue->TakeTaskFromWorkQueue(); task_was_run_bitmap_ |= UINT64_C(1) << queue_index; if (!pending_task.nestable && main_task_runner_->IsNested()) { @@ -713,13 +756,13 @@ bool TaskQueueManager::PostDelayedTask( const tracked_objects::Location& from_here, const base::Closure& task, base::TimeDelta delay) { - DCHECK(delay > base::TimeDelta()); + DCHECK_GE(delay, base::TimeDelta()); return main_task_runner_->PostDelayedTask(from_here, task, delay); } void TaskQueueManager::SetQueueName(size_t queue_index, const char* name) { DCHECK(main_thread_checker_.CalledOnValidThread()); - internal::TaskQueue* queue = Queue(queue_index); + internal::TaskQueueImpl* queue = Queue(queue_index); queue->set_name(name); } diff --git a/components/scheduler/child/task_queue_manager.h b/components/scheduler/child/task_queue_manager.h index 5fe5c46..3b8e514 100644 --- a/components/scheduler/child/task_queue_manager.h +++ b/components/scheduler/child/task_queue_manager.h @@ -11,7 +11,6 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/pending_task.h" -#include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" #include "components/scheduler/child/task_queue_selector.h" @@ -26,9 +25,10 @@ class TickClock; } namespace scheduler { +class TaskQueue; namespace internal { class LazyNow; -class TaskQueue; +class TaskQueueImpl; } class NestableSingleThreadTaskRunner; class TaskQueueSelector; @@ -107,8 +107,7 @@ class SCHEDULER_EXPORT TaskQueueManager : public TaskQueueSelector::Observer { ~TaskQueueManager() override; // Returns the task runner which targets the queue selected by |queue_index|. - scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerForQueue( - size_t queue_index) const; + scoped_refptr<TaskQueue> TaskRunnerForQueue(size_t queue_index) const; // Sets the pump policy for the |queue_index| to |pump_policy|. By // default queues are created with AUTO_PUMP_POLICY. @@ -169,7 +168,7 @@ class SCHEDULER_EXPORT TaskQueueManager : public TaskQueueSelector::Observer { void OnTaskQueueEnabled() override; friend class internal::LazyNow; - friend class internal::TaskQueue; + friend class internal::TaskQueueImpl; friend class TaskQueueManagerTest; class DeletionSentinel : public base::RefCounted<DeletionSentinel> { @@ -219,7 +218,7 @@ class SCHEDULER_EXPORT TaskQueueManager : public TaskQueueSelector::Observer { bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, const base::Closure& task, base::TimeDelta delay); - internal::TaskQueue* Queue(size_t queue_index) const; + internal::TaskQueueImpl* Queue(size_t queue_index) const; base::TimeTicks Now() const; @@ -230,7 +229,7 @@ class SCHEDULER_EXPORT TaskQueueManager : public TaskQueueSelector::Observer { static const char* PumpPolicyToString(PumpPolicy pump_policy); static const char* WakeupPolicyToString(WakeupPolicy wakeup_policy); - std::vector<scoped_refptr<internal::TaskQueue>> queues_; + std::vector<scoped_refptr<internal::TaskQueueImpl>> queues_; base::AtomicSequenceNumber task_sequence_num_; base::debug::TaskAnnotator task_annotator_; diff --git a/components/scheduler/child/task_queue_manager_perftest.cc b/components/scheduler/child/task_queue_manager_perftest.cc index 7855557..3279917 100644 --- a/components/scheduler/child/task_queue_manager_perftest.cc +++ b/components/scheduler/child/task_queue_manager_perftest.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/threading/thread.h" #include "components/scheduler/child/scheduler_message_loop_delegate.h" +#include "components/scheduler/child/task_queue.h" #include "components/scheduler/child/task_queue_selector.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_test.h" diff --git a/components/scheduler/child/task_queue_manager_unittest.cc b/components/scheduler/child/task_queue_manager_unittest.cc index 55f738f..8b6839b 100644 --- a/components/scheduler/child/task_queue_manager_unittest.cc +++ b/components/scheduler/child/task_queue_manager_unittest.cc @@ -11,6 +11,7 @@ #include "cc/test/ordered_simple_task_runner.h" #include "components/scheduler/child/nestable_task_runner_for_test.h" #include "components/scheduler/child/scheduler_message_loop_delegate.h" +#include "components/scheduler/child/task_queue.h" #include "components/scheduler/child/task_queue_selector.h" #include "components/scheduler/child/test_time_source.h" #include "components/scheduler/test/test_always_fail_time_source.h" @@ -1297,4 +1298,34 @@ TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) { EXPECT_THAT(run_order, ElementsAre(2, 1)); } +TEST_F(TaskQueueManagerTest, DelayedTaskWithAbsoluteRunTime) { + Initialize(1u, SelectorType::Automatic); + + scoped_refptr<TaskQueue> runner = manager_->TaskRunnerForQueue(0); + + std::vector<int> run_order; + + // One task in the past, two with the exact same run time and one in the + // future. + base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); + base::TimeTicks runTime1 = now_src_->NowTicks() - delay; + base::TimeTicks runTime2 = now_src_->NowTicks(); + base::TimeTicks runTime3 = now_src_->NowTicks(); + base::TimeTicks runTime4 = now_src_->NowTicks() + delay; + + runner->PostDelayedTaskAt(FROM_HERE, base::Bind(&TestTask, 1, &run_order), + runTime1); + runner->PostDelayedTaskAt(FROM_HERE, base::Bind(&TestTask, 2, &run_order), + runTime2); + runner->PostDelayedTaskAt(FROM_HERE, base::Bind(&TestTask, 3, &run_order), + runTime3); + runner->PostDelayedTaskAt(FROM_HERE, base::Bind(&TestTask, 4, &run_order), + runTime4); + + now_src_->Advance(2 * delay); + test_task_runner_->RunUntilIdle(); + + EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); +} + } // namespace scheduler diff --git a/components/scheduler/child/web_scheduler_impl.cc b/components/scheduler/child/web_scheduler_impl.cc index 0a91875..6b56cc0 100644 --- a/components/scheduler/child/web_scheduler_impl.cc +++ b/components/scheduler/child/web_scheduler_impl.cc @@ -15,12 +15,11 @@ WebSchedulerImpl::WebSchedulerImpl( ChildScheduler* child_scheduler, scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner, scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner) + scoped_refptr<TaskQueue> timer_task_runner) : child_scheduler_(child_scheduler), idle_task_runner_(idle_task_runner), loading_task_runner_(loading_task_runner), - timer_task_runner_(timer_task_runner) { -} + timer_task_runner_(timer_task_runner) {} WebSchedulerImpl::~WebSchedulerImpl() { } @@ -107,4 +106,18 @@ void WebSchedulerImpl::postTimerTask( base::TimeDelta::FromMilliseconds(delayMs)); } +void WebSchedulerImpl::postTimerTaskAt( + const blink::WebTraceLocation& web_location, + blink::WebThread::Task* task, + double monotonicTime) { + DCHECK(timer_task_runner_); + scoped_ptr<blink::WebThread::Task> scoped_task(task); + tracked_objects::Location location(web_location.functionName(), + web_location.fileName(), -1, nullptr); + timer_task_runner_->PostDelayedTaskAt( + location, + base::Bind(&WebSchedulerImpl::runTask, base::Passed(&scoped_task)), + base::TimeTicks() + base::TimeDelta::FromSecondsD(monotonicTime)); +} + } // namespace scheduler diff --git a/components/scheduler/child/web_scheduler_impl.h b/components/scheduler/child/web_scheduler_impl.h index 4d2cf59..44dcb0f 100644 --- a/components/scheduler/child/web_scheduler_impl.h +++ b/components/scheduler/child/web_scheduler_impl.h @@ -20,6 +20,7 @@ namespace scheduler { class ChildScheduler; class SingleThreadIdleTaskRunner; +class TaskQueue; class SCHEDULER_EXPORT WebSchedulerImpl : public blink::WebScheduler { public: @@ -27,7 +28,7 @@ class SCHEDULER_EXPORT WebSchedulerImpl : public blink::WebScheduler { ChildScheduler* child_scheduler, scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner, scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner); + scoped_refptr<TaskQueue> timer_task_runner); ~WebSchedulerImpl() override; // blink::WebScheduler implementation: @@ -42,6 +43,11 @@ class SCHEDULER_EXPORT WebSchedulerImpl : public blink::WebScheduler { blink::WebThread::IdleTask* task); virtual void postLoadingTask(const blink::WebTraceLocation& location, blink::WebThread::Task* task); + virtual void postTimerTaskAt(const blink::WebTraceLocation& location, + blink::WebThread::Task* task, + double monotonicTime); + + // TODO(skyostil): Remove once the Blink side patch lands. virtual void postTimerTask(const blink::WebTraceLocation& location, blink::WebThread::Task* task, long long delayMs); @@ -54,7 +60,7 @@ class SCHEDULER_EXPORT WebSchedulerImpl : public blink::WebScheduler { ChildScheduler* child_scheduler_; // NOT OWNED scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_; + scoped_refptr<TaskQueue> timer_task_runner_; }; } // namespace scheduler diff --git a/components/scheduler/child/worker_scheduler_impl.cc b/components/scheduler/child/worker_scheduler_impl.cc index b5b9c83..21774d5 100644 --- a/components/scheduler/child/worker_scheduler_impl.cc +++ b/components/scheduler/child/worker_scheduler_impl.cc @@ -40,8 +40,7 @@ void WorkerSchedulerImpl::Init() { idle_helper_.EnableLongIdlePeriod(); } -scoped_refptr<base::SingleThreadTaskRunner> -WorkerSchedulerImpl::DefaultTaskRunner() { +scoped_refptr<TaskQueue> WorkerSchedulerImpl::DefaultTaskRunner() { DCHECK(initialized_); return helper_.DefaultTaskRunner(); } diff --git a/components/scheduler/child/worker_scheduler_impl.h b/components/scheduler/child/worker_scheduler_impl.h index 5616a54..24b044c 100644 --- a/components/scheduler/child/worker_scheduler_impl.h +++ b/components/scheduler/child/worker_scheduler_impl.h @@ -28,7 +28,7 @@ class SCHEDULER_EXPORT WorkerSchedulerImpl : public WorkerScheduler, ~WorkerSchedulerImpl() override; // WorkerScheduler implementation: - scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; + scoped_refptr<TaskQueue> DefaultTaskRunner() override; scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override; bool CanExceedIdleDeadlineIfRequired() const override; bool ShouldYieldForHighPriorityWork() override; diff --git a/components/scheduler/renderer/null_renderer_scheduler.cc b/components/scheduler/renderer/null_renderer_scheduler.cc index e5052ad..11b577f 100644 --- a/components/scheduler/renderer/null_renderer_scheduler.cc +++ b/components/scheduler/renderer/null_renderer_scheduler.cc @@ -8,19 +8,18 @@ #include "base/message_loop/message_loop.h" #include "base/thread_task_runner_handle.h" #include "components/scheduler/child/null_idle_task_runner.h" +#include "components/scheduler/child/null_task_queue.h" namespace scheduler { NullRendererScheduler::NullRendererScheduler() - : task_runner_(base::ThreadTaskRunnerHandle::Get()), - idle_task_runner_(new NullIdleTaskRunner()) { -} + : task_runner_(new NullTaskQueue(base::ThreadTaskRunnerHandle::Get())), + idle_task_runner_(new NullIdleTaskRunner()) {} NullRendererScheduler::~NullRendererScheduler() { } -scoped_refptr<base::SingleThreadTaskRunner> -NullRendererScheduler::DefaultTaskRunner() { +scoped_refptr<TaskQueue> NullRendererScheduler::DefaultTaskRunner() { return task_runner_; } @@ -39,8 +38,7 @@ NullRendererScheduler::IdleTaskRunner() { return idle_task_runner_; } -scoped_refptr<base::SingleThreadTaskRunner> -NullRendererScheduler::TimerTaskRunner() { +scoped_refptr<TaskQueue> NullRendererScheduler::TimerTaskRunner() { return task_runner_; } diff --git a/components/scheduler/renderer/null_renderer_scheduler.h b/components/scheduler/renderer/null_renderer_scheduler.h index 753bc9a..b989e07 100644 --- a/components/scheduler/renderer/null_renderer_scheduler.h +++ b/components/scheduler/renderer/null_renderer_scheduler.h @@ -8,17 +8,18 @@ #include "components/scheduler/renderer/renderer_scheduler.h" namespace scheduler { +class NullTaskQueue; class NullRendererScheduler : public RendererScheduler { public: NullRendererScheduler(); ~NullRendererScheduler() override; - scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; + scoped_refptr<TaskQueue> DefaultTaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() override; scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override; - scoped_refptr<base::SingleThreadTaskRunner> TimerTaskRunner() override; + scoped_refptr<TaskQueue> TimerTaskRunner() override; void WillBeginFrame(const cc::BeginFrameArgs& args) override; void BeginFrameNotExpectedSoon() override; @@ -43,7 +44,7 @@ class NullRendererScheduler : public RendererScheduler { void ResumeTimerQueue() override; private: - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + scoped_refptr<NullTaskQueue> task_runner_; scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; DISALLOW_COPY_AND_ASSIGN(NullRendererScheduler); diff --git a/components/scheduler/renderer/renderer_scheduler.h b/components/scheduler/renderer/renderer_scheduler.h index 2348511..c5955b5 100644 --- a/components/scheduler/renderer/renderer_scheduler.h +++ b/components/scheduler/renderer/renderer_scheduler.h @@ -31,7 +31,7 @@ class SCHEDULER_EXPORT RendererScheduler : public ChildScheduler { virtual scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() = 0; // Returns the timer task runner. This queue is intended for DOM Timers. - virtual scoped_refptr<base::SingleThreadTaskRunner> TimerTaskRunner() = 0; + virtual scoped_refptr<TaskQueue> TimerTaskRunner() = 0; // Called to notify about the start of an extended period where no frames // need to be drawn. Must be called from the main thread. diff --git a/components/scheduler/renderer/renderer_scheduler_impl.cc b/components/scheduler/renderer/renderer_scheduler_impl.cc index 51c51ae..a885387 100644 --- a/components/scheduler/renderer/renderer_scheduler_impl.cc +++ b/components/scheduler/renderer/renderer_scheduler_impl.cc @@ -11,6 +11,7 @@ #include "cc/output/begin_frame_args.h" #include "components/scheduler/child/nestable_single_thread_task_runner.h" #include "components/scheduler/child/prioritizing_task_queue_selector.h" +#include "components/scheduler/child/task_queue.h" namespace scheduler { @@ -89,8 +90,7 @@ void RendererSchedulerImpl::Shutdown() { MainThreadOnly().was_shutdown_ = true; } -scoped_refptr<base::SingleThreadTaskRunner> -RendererSchedulerImpl::DefaultTaskRunner() { +scoped_refptr<TaskQueue> RendererSchedulerImpl::DefaultTaskRunner() { return helper_.DefaultTaskRunner(); } @@ -111,8 +111,7 @@ RendererSchedulerImpl::LoadingTaskRunner() { return loading_task_runner_; } -scoped_refptr<base::SingleThreadTaskRunner> -RendererSchedulerImpl::TimerTaskRunner() { +scoped_refptr<TaskQueue> RendererSchedulerImpl::TimerTaskRunner() { helper_.CheckOnValidThread(); return timer_task_runner_; } diff --git a/components/scheduler/renderer/renderer_scheduler_impl.h b/components/scheduler/renderer/renderer_scheduler_impl.h index a6c2138..e251538 100644 --- a/components/scheduler/renderer/renderer_scheduler_impl.h +++ b/components/scheduler/renderer/renderer_scheduler_impl.h @@ -30,11 +30,11 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler, ~RendererSchedulerImpl() override; // RendererScheduler implementation: - scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; + scoped_refptr<TaskQueue> DefaultTaskRunner() override; scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() override; - scoped_refptr<base::SingleThreadTaskRunner> TimerTaskRunner() override; + scoped_refptr<TaskQueue> TimerTaskRunner() override; void WillBeginFrame(const cc::BeginFrameArgs& args) override; void BeginFrameNotExpectedSoon() override; void DidCommitFrameToCompositor() override; @@ -199,7 +199,7 @@ class SCHEDULER_EXPORT RendererSchedulerImpl : public RendererScheduler, const scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; const scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; - const scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_; + const scoped_refptr<TaskQueue> timer_task_runner_; base::Closure update_policy_closure_; DeadlineTaskRunner delayed_update_policy_runner_; diff --git a/components/scheduler/renderer/renderer_web_scheduler_impl.cc b/components/scheduler/renderer/renderer_web_scheduler_impl.cc index b54bf9a..c833b70 100644 --- a/components/scheduler/renderer/renderer_web_scheduler_impl.cc +++ b/components/scheduler/renderer/renderer_web_scheduler_impl.cc @@ -4,6 +4,7 @@ #include "components/scheduler/renderer/renderer_web_scheduler_impl.h" +#include "components/scheduler/child/task_queue.h" #include "components/scheduler/renderer/renderer_scheduler.h" namespace scheduler { diff --git a/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc b/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc index 2822456..b7720b1 100644 --- a/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc +++ b/components/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc @@ -4,6 +4,7 @@ #include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h" +#include "components/scheduler/child/task_queue.h" #include "components/scheduler/renderer/renderer_scheduler.h" #include "components/scheduler/renderer/renderer_web_scheduler_impl.h" #include "third_party/WebKit/public/platform/WebTraceLocation.h" diff --git a/components/scheduler/scheduler.gypi b/components/scheduler/scheduler.gypi index e0d4bee..9f8e970 100644 --- a/components/scheduler/scheduler.gypi +++ b/components/scheduler/scheduler.gypi @@ -17,6 +17,8 @@ 'child/nestable_single_thread_task_runner.h', 'child/null_idle_task_runner.cc', 'child/null_idle_task_runner.h', + 'child/null_task_queue.cc', + 'child/null_task_queue.h', 'child/null_worker_scheduler.cc', 'child/null_worker_scheduler.h', 'child/pollable_thread_safe_flag.cc', @@ -29,6 +31,7 @@ 'child/scheduler_message_loop_delegate.h', 'child/single_thread_idle_task_runner.cc', 'child/single_thread_idle_task_runner.h', + 'child/task_queue.h', 'child/task_queue_manager.cc', 'child/task_queue_manager.h', 'child/task_queue_selector.h', |