blob: fdc3859c30a19f1add42e778adb02d8ccfc7d3f9 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "perfetto_base/test/test_task_runner.h"
#include <stdio.h>
#include <unistd.h>
#include <chrono>
#include "perfetto_base/logging.h"
namespace perfetto {
namespace base {
TestTaskRunner::TestTaskRunner() = default;
TestTaskRunner::~TestTaskRunner() = default;
void TestTaskRunner::Run() {
PERFETTO_DCHECK_THREAD(thread_checker_);
for (;;)
task_runner_.Run();
}
void TestTaskRunner::RunUntilIdle() {
PERFETTO_DCHECK_THREAD(thread_checker_);
task_runner_.PostTask(std::bind(&TestTaskRunner::QuitIfIdle, this));
task_runner_.Run();
}
void TestTaskRunner::QuitIfIdle() {
PERFETTO_DCHECK_THREAD(thread_checker_);
if (task_runner_.IsIdleForTesting()) {
task_runner_.Quit();
return;
}
task_runner_.PostTask(std::bind(&TestTaskRunner::QuitIfIdle, this));
}
void TestTaskRunner::RunUntilCheckpoint(const std::string& checkpoint,
int timeout_ms) {
PERFETTO_DCHECK_THREAD(thread_checker_);
if (checkpoints_.count(checkpoint) == 0) {
fprintf(stderr, "[TestTaskRunner] Checkpoint \"%s\" does not exist.\n",
checkpoint.c_str());
abort();
}
if (checkpoints_[checkpoint])
return;
task_runner_.PostDelayedTask(
[this, checkpoint] {
if (checkpoints_[checkpoint])
return;
fprintf(stderr, "[TestTaskRunner] Failed to reach checkpoint \"%s\"\n",
checkpoint.c_str());
abort();
},
timeout_ms);
pending_checkpoint_ = checkpoint;
task_runner_.Run();
}
std::function<void()> TestTaskRunner::CreateCheckpoint(
const std::string& checkpoint) {
PERFETTO_DCHECK_THREAD(thread_checker_);
PERFETTO_DCHECK(checkpoints_.count(checkpoint) == 0);
auto checkpoint_iter = checkpoints_.emplace(checkpoint, false);
return [this, checkpoint_iter] {
checkpoint_iter.first->second = true;
if (pending_checkpoint_ == checkpoint_iter.first->first) {
pending_checkpoint_.clear();
task_runner_.Quit();
}
};
}
// TaskRunner implementation.
void TestTaskRunner::PostTask(std::function<void()> closure) {
task_runner_.PostTask(std::move(closure));
}
void TestTaskRunner::PostDelayedTask(std::function<void()> closure,
int delay_ms) {
task_runner_.PostDelayedTask(std::move(closure), delay_ms);
}
void TestTaskRunner::AddFileDescriptorWatch(int fd,
std::function<void()> callback) {
task_runner_.AddFileDescriptorWatch(fd, std::move(callback));
}
void TestTaskRunner::RemoveFileDescriptorWatch(int fd) {
task_runner_.RemoveFileDescriptorWatch(fd);
}
} // namespace base
} // namespace perfetto