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 #include <unistd.h>
21
22 #include <chrono>
23
24 #include "perfetto/base/logging.h"
25
26 namespace perfetto {
27 namespace base {
28
29 TestTaskRunner::TestTaskRunner() = default;
30
31 TestTaskRunner::~TestTaskRunner() = default;
32
Run()33 void TestTaskRunner::Run() {
34 PERFETTO_DCHECK_THREAD(thread_checker_);
35 for (;;)
36 task_runner_.Run();
37 }
38
RunUntilIdle()39 void TestTaskRunner::RunUntilIdle() {
40 PERFETTO_DCHECK_THREAD(thread_checker_);
41 task_runner_.PostTask(std::bind(&TestTaskRunner::QuitIfIdle, this));
42 task_runner_.Run();
43 }
44
QuitIfIdle()45 void TestTaskRunner::QuitIfIdle() {
46 PERFETTO_DCHECK_THREAD(thread_checker_);
47 if (task_runner_.IsIdleForTesting()) {
48 task_runner_.Quit();
49 return;
50 }
51 task_runner_.PostTask(std::bind(&TestTaskRunner::QuitIfIdle, this));
52 }
53
RunUntilCheckpoint(const std::string & checkpoint,uint32_t timeout_ms)54 void TestTaskRunner::RunUntilCheckpoint(const std::string& checkpoint,
55 uint32_t timeout_ms) {
56 PERFETTO_DCHECK_THREAD(thread_checker_);
57 if (checkpoints_.count(checkpoint) == 0) {
58 PERFETTO_FATAL("[TestTaskRunner] Checkpoint \"%s\" does not exist.\n",
59 checkpoint.c_str());
60 }
61 if (checkpoints_[checkpoint])
62 return;
63
64 task_runner_.PostDelayedTask(
65 [this, checkpoint] {
66 if (checkpoints_[checkpoint])
67 return;
68 PERFETTO_FATAL("[TestTaskRunner] Failed to reach checkpoint \"%s\"\n",
69 checkpoint.c_str());
70 },
71 timeout_ms);
72
73 pending_checkpoint_ = checkpoint;
74 task_runner_.Run();
75 }
76
CreateCheckpoint(const std::string & checkpoint)77 std::function<void()> TestTaskRunner::CreateCheckpoint(
78 const std::string& checkpoint) {
79 PERFETTO_DCHECK_THREAD(thread_checker_);
80 PERFETTO_DCHECK(checkpoints_.count(checkpoint) == 0);
81 auto checkpoint_iter = checkpoints_.emplace(checkpoint, false);
82 return [this, checkpoint_iter] {
83 PERFETTO_DCHECK_THREAD(thread_checker_);
84 checkpoint_iter.first->second = true;
85 if (pending_checkpoint_ == checkpoint_iter.first->first) {
86 pending_checkpoint_.clear();
87 task_runner_.Quit();
88 }
89 };
90 }
91
92 // TaskRunner implementation.
PostTask(std::function<void ()> closure)93 void TestTaskRunner::PostTask(std::function<void()> closure) {
94 task_runner_.PostTask(std::move(closure));
95 }
96
PostDelayedTask(std::function<void ()> closure,uint32_t delay_ms)97 void TestTaskRunner::PostDelayedTask(std::function<void()> closure,
98 uint32_t delay_ms) {
99 task_runner_.PostDelayedTask(std::move(closure), delay_ms);
100 }
101
AddFileDescriptorWatch(int fd,std::function<void ()> callback)102 void TestTaskRunner::AddFileDescriptorWatch(int fd,
103 std::function<void()> callback) {
104 task_runner_.AddFileDescriptorWatch(fd, std::move(callback));
105 }
106
RemoveFileDescriptorWatch(int fd)107 void TestTaskRunner::RemoveFileDescriptorWatch(int fd) {
108 task_runner_.RemoveFileDescriptorWatch(fd);
109 }
110
RunsTasksOnCurrentThread() const111 bool TestTaskRunner::RunsTasksOnCurrentThread() const {
112 return task_runner_.RunsTasksOnCurrentThread();
113 }
114
115 } // namespace base
116 } // namespace perfetto
117