mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 06:16:30 +03:00
96 lines
3.0 KiB
C++
96 lines
3.0 KiB
C++
// 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 <algorithm>
|
|
|
|
#include "base/bind.h"
|
|
#include "base/logging.h"
|
|
#include "base/task_runner.h"
|
|
#include "base/task_scheduler/task.h"
|
|
|
|
namespace base {
|
|
namespace internal {
|
|
|
|
DelayedTaskManager::DelayedTaskManager(
|
|
std::unique_ptr<const TickClock> tick_clock)
|
|
: tick_clock_(std::move(tick_clock)) {
|
|
DCHECK(tick_clock_);
|
|
}
|
|
|
|
DelayedTaskManager::~DelayedTaskManager() = default;
|
|
|
|
void DelayedTaskManager::Start(
|
|
scoped_refptr<TaskRunner> service_thread_task_runner) {
|
|
DCHECK(service_thread_task_runner);
|
|
|
|
decltype(tasks_added_before_start_) tasks_added_before_start;
|
|
|
|
{
|
|
AutoSchedulerLock auto_lock(lock_);
|
|
DCHECK(!service_thread_task_runner_);
|
|
DCHECK(!started_.IsSet());
|
|
service_thread_task_runner_ = std::move(service_thread_task_runner);
|
|
tasks_added_before_start = std::move(tasks_added_before_start_);
|
|
// |service_thread_task_runner_| must not change after |started_| is set
|
|
// (cf. comment above |lock_| in header file).
|
|
started_.Set();
|
|
}
|
|
|
|
const TimeTicks now = tick_clock_->NowTicks();
|
|
for (auto& task_and_callback : tasks_added_before_start) {
|
|
const TimeDelta delay =
|
|
std::max(TimeDelta(), task_and_callback.first.delayed_run_time - now);
|
|
AddDelayedTaskNow(std::move(task_and_callback.first), delay,
|
|
std::move(task_and_callback.second));
|
|
}
|
|
}
|
|
|
|
void DelayedTaskManager::AddDelayedTask(
|
|
Task task,
|
|
PostTaskNowCallback post_task_now_callback) {
|
|
DCHECK(task.task);
|
|
|
|
const TimeDelta delay = task.delay;
|
|
DCHECK(!delay.is_zero());
|
|
|
|
// Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
|
|
// for details.
|
|
CHECK(task.task);
|
|
|
|
// If |started_| is set, the DelayedTaskManager is in a stable state and
|
|
// AddDelayedTaskNow() can be called without synchronization. Otherwise, it is
|
|
// necessary to acquire |lock_| and recheck.
|
|
if (started_.IsSet()) {
|
|
AddDelayedTaskNow(std::move(task), delay,
|
|
std::move(post_task_now_callback));
|
|
} else {
|
|
AutoSchedulerLock auto_lock(lock_);
|
|
if (started_.IsSet()) {
|
|
AddDelayedTaskNow(std::move(task), delay,
|
|
std::move(post_task_now_callback));
|
|
} else {
|
|
tasks_added_before_start_.push_back(
|
|
{std::move(task), std::move(post_task_now_callback)});
|
|
}
|
|
}
|
|
}
|
|
|
|
void DelayedTaskManager::AddDelayedTaskNow(
|
|
Task task,
|
|
TimeDelta delay,
|
|
PostTaskNowCallback post_task_now_callback) {
|
|
DCHECK(task.task);
|
|
DCHECK(started_.IsSet());
|
|
// TODO(fdoray): Use |task->delayed_run_time| on the service thread
|
|
// MessageLoop rather than recomputing it from |delay|.
|
|
service_thread_task_runner_->PostDelayedTask(
|
|
FROM_HERE, BindOnce(std::move(post_task_now_callback), std::move(task)),
|
|
delay);
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace base
|