1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "src/base/test/test_task_runner.h"
18
19 #include <stdio.h>
20
21 #include <chrono>
22
23 #include "perfetto/base/logging.h"
24
25 namespace perfetto {
26 namespace base {
27
28 TestTaskRunner::TestTaskRunner() = default;
29
30 TestTaskRunner::~TestTaskRunner() = default;
31
Run()32 void TestTaskRunner::Run() {
33 PERFETTO_DCHECK_THREAD(thread_checker_);
34 for (;;)
35 task_runner_.Run();
36 }
37
RunUntilIdle()38 void TestTaskRunner::RunUntilIdle() {
39 PERFETTO_DCHECK_THREAD(thread_checker_);
40 task_runner_.PostTask(std::bind(&TestTaskRunner::QuitIfIdle, this));
41 task_runner_.Run();
42 }
43
QuitIfIdle()44 void TestTaskRunner::QuitIfIdle() {
45 PERFETTO_DCHECK_THREAD(thread_checker_);
46 if (task_runner_.IsIdleForTesting()) {
47 task_runner_.Quit();
48 return;
49 }
50 task_runner_.PostTask(std::bind(&TestTaskRunner::QuitIfIdle, this));
51 }
52
RunUntilCheckpoint(const std::string & checkpoint,uint32_t timeout_ms)53 void TestTaskRunner::RunUntilCheckpoint(const std::string& checkpoint,
54 uint32_t timeout_ms) {
55 PERFETTO_DCHECK_THREAD(thread_checker_);
56 if (checkpoints_.count(checkpoint) == 0) {
57 PERFETTO_FATAL("[TestTaskRunner] Checkpoint \"%s\" does not exist.\n",
58 checkpoint.c_str());
59 }
60 if (checkpoints_[checkpoint])
61 return;
62
63 task_runner_.PostDelayedTask(
64 [this, checkpoint] {
65 if (checkpoints_[checkpoint])
66 return;
67 PERFETTO_FATAL("[TestTaskRunner] Failed to reach checkpoint \"%s\"\n",
68 checkpoint.c_str());
69 },
70 timeout_ms);
71
72 pending_checkpoint_ = checkpoint;
73 task_runner_.Run();
74 }
75
CreateCheckpoint(const std::string & checkpoint)76 std::function<void()> TestTaskRunner::CreateCheckpoint(
77 const std::string& checkpoint) {
78 PERFETTO_DCHECK_THREAD(thread_checker_);
79 PERFETTO_DCHECK(checkpoints_.count(checkpoint) == 0);
80 auto checkpoint_iter = checkpoints_.emplace(checkpoint, false);
81 return [this, checkpoint_iter] {
82 PERFETTO_DCHECK_THREAD(thread_checker_);
83 checkpoint_iter.first->second = true;
84 if (pending_checkpoint_ == checkpoint_iter.first->first) {
85 pending_checkpoint_.clear();
86 task_runner_.Quit();
87 }
88 };
89 }
90
91 // TaskRunner implementation.
PostTask(std::function<void ()> closure)92 void TestTaskRunner::PostTask(std::function<void()> closure) {
93 task_runner_.PostTask(std::move(closure));
94 }
95
PostDelayedTask(std::function<void ()> closure,uint32_t delay_ms)96 void TestTaskRunner::PostDelayedTask(std::function<void()> closure,
97 uint32_t delay_ms) {
98 task_runner_.PostDelayedTask(std::move(closure), delay_ms);
99 }
100
AddFileDescriptorWatch(PlatformHandle fd,std::function<void ()> callback)101 void TestTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
102 std::function<void()> callback) {
103 task_runner_.AddFileDescriptorWatch(fd, std::move(callback));
104 }
105
RemoveFileDescriptorWatch(PlatformHandle fd)106 void TestTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
107 task_runner_.RemoveFileDescriptorWatch(fd);
108 }
109
RunsTasksOnCurrentThread() const110 bool TestTaskRunner::RunsTasksOnCurrentThread() const {
111 return task_runner_.RunsTasksOnCurrentThread();
112 }
113
114 } // namespace base
115 } // namespace perfetto
116