| Index: base/task_scheduler/delayed_task_manager.cc
|
| diff --git a/base/task_scheduler/delayed_task_manager.cc b/base/task_scheduler/delayed_task_manager.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fda8d3bba0d0245ee3297647dc9ff56825e88b65
|
| --- /dev/null
|
| +++ b/base/task_scheduler/delayed_task_manager.cc
|
| @@ -0,0 +1,106 @@
|
| +// Copyright 2016 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 "base/task_scheduler/delayed_task_manager.h"
|
| +
|
| +#include <vector>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/task_scheduler/utils.h"
|
| +
|
| +namespace base {
|
| +namespace internal {
|
| +
|
| +DelayedTaskManager::DelayedTaskManager(const Closure& delayed_run_time_changed,
|
| + ShutdownManager* shutdown_manager)
|
| + : next_delayed_task_index_(0),
|
| + delayed_run_time_changed_(delayed_run_time_changed),
|
| + shutdown_manager_(shutdown_manager) {
|
| + DCHECK(!delayed_run_time_changed_.is_null());
|
| + DCHECK(shutdown_manager_);
|
| +}
|
| +
|
| +DelayedTaskManager::~DelayedTaskManager() = default;
|
| +
|
| +void DelayedTaskManager::AddDelayedTask(const Task& task,
|
| + scoped_refptr<Sequence> sequence,
|
| + PriorityQueue* priority_queue) {
|
| + DCHECK_NE(TimeTicks(), task.delayed_run_time);
|
| + DCHECK(sequence.get());
|
| + DCHECK(priority_queue);
|
| +
|
| + TimeTicks previous_delayed_run_time;
|
| +
|
| + {
|
| + AutoSchedulerLock auto_lock(lock_);
|
| +
|
| + DelayedTask delayed_task;
|
| + delayed_task.task = task;
|
| + delayed_task.sequence = sequence;
|
| + delayed_task.priority_queue = priority_queue;
|
| + delayed_task.index = next_delayed_task_index_;
|
| + ++next_delayed_task_index_;
|
| +
|
| + if (!delayed_tasks_.empty())
|
| + previous_delayed_run_time = delayed_tasks_.top().task.delayed_run_time;
|
| +
|
| + delayed_tasks_.push(delayed_task);
|
| + }
|
| +
|
| + if (previous_delayed_run_time.is_null() ||
|
| + task.delayed_run_time < previous_delayed_run_time) {
|
| + delayed_run_time_changed_.Run();
|
| + }
|
| +}
|
| +
|
| +void DelayedTaskManager::PostReadyTasks() {
|
| + // Get delayed tasks that are ready for execution. Don't post them right away
|
| + // to avoid holding multiple locks at the same time.
|
| + const TimeTicks now = Now();
|
| + std::vector<DelayedTask> ready_tasks;
|
| +
|
| + {
|
| + AutoSchedulerLock auto_lock(lock_);
|
| + while (!delayed_tasks_.empty() &&
|
| + delayed_tasks_.top().task.delayed_run_time <= now) {
|
| + ready_tasks.push_back(delayed_tasks_.top());
|
| + delayed_tasks_.pop();
|
| + }
|
| + }
|
| +
|
| + // Post delayed tasks that are ready for execution.
|
| + for (const auto& delayed_task : ready_tasks) {
|
| + PostTaskNowHelper(delayed_task.task, delayed_task.sequence,
|
| + delayed_task.priority_queue, shutdown_manager_);
|
| + }
|
| +}
|
| +
|
| +TimeTicks DelayedTaskManager::GetNextDelayedRunTime() const {
|
| + AutoSchedulerLock auto_lock(lock_);
|
| +
|
| + if (delayed_tasks_.empty())
|
| + return TimeTicks();
|
| +
|
| + return delayed_tasks_.top().task.delayed_run_time;
|
| +}
|
| +
|
| +TimeTicks DelayedTaskManager::Now() {
|
| + return TimeTicks::Now();
|
| +}
|
| +
|
| +DelayedTaskManager::DelayedTask::DelayedTask() = default;
|
| +
|
| +DelayedTaskManager::DelayedTask::~DelayedTask() = default;
|
| +
|
| +bool DelayedTaskManager::DelayedTask::operator<(
|
| + const DelayedTask& other) const {
|
| + if (task.delayed_run_time > other.task.delayed_run_time)
|
| + return true;
|
| + if (task.delayed_run_time < other.task.delayed_run_time)
|
| + return false;
|
| + return index > other.index;
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace base
|
|
|