xref: /aosp_15_r20/external/perfetto/src/base/test/test_task_runner.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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 
AdvanceTimeAndRunUntilIdle(uint32_t ms)91 void TestTaskRunner::AdvanceTimeAndRunUntilIdle(uint32_t ms) {
92   PERFETTO_DCHECK_THREAD(thread_checker_);
93   task_runner_.PostDelayedTask(std::bind(&TestTaskRunner::QuitIfIdle, this),
94                                ms);
95   task_runner_.AdvanceTimeForTesting(ms);
96   task_runner_.Run();
97 }
98 
99 // TaskRunner implementation.
PostTask(std::function<void ()> closure)100 void TestTaskRunner::PostTask(std::function<void()> closure) {
101   task_runner_.PostTask(std::move(closure));
102 }
103 
PostDelayedTask(std::function<void ()> closure,uint32_t delay_ms)104 void TestTaskRunner::PostDelayedTask(std::function<void()> closure,
105                                      uint32_t delay_ms) {
106   task_runner_.PostDelayedTask(std::move(closure), delay_ms);
107 }
108 
AddFileDescriptorWatch(PlatformHandle fd,std::function<void ()> callback)109 void TestTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
110                                             std::function<void()> callback) {
111   task_runner_.AddFileDescriptorWatch(fd, std::move(callback));
112 }
113 
RemoveFileDescriptorWatch(PlatformHandle fd)114 void TestTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
115   task_runner_.RemoveFileDescriptorWatch(fd);
116 }
117 
RunsTasksOnCurrentThread() const118 bool TestTaskRunner::RunsTasksOnCurrentThread() const {
119   return task_runner_.RunsTasksOnCurrentThread();
120 }
121 
122 }  // namespace base
123 }  // namespace perfetto
124