blob: 17e9a9ac2a06a007023cd4d8a94971c185077afc [file] [log] [blame]
// 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 "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h"
#include <algorithm>
#include <utility>
#include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
namespace blink {
namespace scheduler {
class FakeTaskRunner::Data : public WTF::ThreadSafeRefCounted<Data> {
public:
Data() = default;
void PostDelayedTask(base::OnceClosure task, base::TimeDelta delay) {
task_queue_.emplace_back(std::move(task), time_ + delay);
}
using PendingTask = FakeTaskRunner::PendingTask;
Deque<PendingTask>::iterator FindRunnableTask() {
// TODO(tkent): This should return an item which has the minimum |second|.
return std::find_if(
task_queue_.begin(), task_queue_.end(),
[&](const PendingTask& item) { return item.second <= time_; });
}
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
Deque<PendingTask> task_queue_;
base::TimeTicks time_;
private:
~Data() = default;
friend ThreadSafeRefCounted<Data>;
DISALLOW_COPY_AND_ASSIGN(Data);
};
FakeTaskRunner::FakeTaskRunner() : data_(base::AdoptRef(new Data)) {}
FakeTaskRunner::FakeTaskRunner(scoped_refptr<Data> data)
: data_(std::move(data)) {}
FakeTaskRunner::~FakeTaskRunner() = default;
void FakeTaskRunner::SetTime(base::TimeTicks new_time) {
data_->time_ = new_time;
}
bool FakeTaskRunner::RunsTasksInCurrentSequence() const {
return true;
}
void FakeTaskRunner::RunUntilIdle() {
while (!data_->task_queue_.empty()) {
// Move the task to run into a local variable in case it touches the
// task queue by posting a new task.
base::OnceClosure task = std::move(data_->task_queue_.front()).first;
data_->task_queue_.pop_front();
std::move(task).Run();
}
}
void FakeTaskRunner::AdvanceTimeAndRun(base::TimeDelta delta) {
data_->time_ += delta;
for (auto it = data_->FindRunnableTask(); it != data_->task_queue_.end();
it = data_->FindRunnableTask()) {
base::OnceClosure task = std::move(*it).first;
data_->task_queue_.erase(it);
std::move(task).Run();
}
}
Deque<std::pair<base::OnceClosure, base::TimeTicks>>
FakeTaskRunner::TakePendingTasksForTesting() {
return std::move(data_->task_queue_);
}
bool FakeTaskRunner::PostDelayedTask(const base::Location& location,
base::OnceClosure task,
base::TimeDelta delay) {
data_->PostDelayedTask(std::move(task), delay);
return true;
}
bool FakeTaskRunner::PostNonNestableDelayedTask(const base::Location& location,
base::OnceClosure task,
base::TimeDelta delay) {
data_->PostDelayedTask(std::move(task), delay);
return true;
}
} // namespace scheduler
} // namespace blink