• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     fprintf(stderr, "[TestTaskRunner] Checkpoint \"%s\" does not exist.\n",
59             checkpoint.c_str());
60     abort();
61   }
62   if (checkpoints_[checkpoint])
63     return;
64 
65   task_runner_.PostDelayedTask(
66       [this, checkpoint] {
67         if (checkpoints_[checkpoint])
68           return;
69         fprintf(stderr, "[TestTaskRunner] Failed to reach checkpoint \"%s\"\n",
70                 checkpoint.c_str());
71         abort();
72       },
73       timeout_ms);
74 
75   pending_checkpoint_ = checkpoint;
76   task_runner_.Run();
77 }
78 
CreateCheckpoint(const std::string & checkpoint)79 std::function<void()> TestTaskRunner::CreateCheckpoint(
80     const std::string& checkpoint) {
81   PERFETTO_DCHECK_THREAD(thread_checker_);
82   PERFETTO_DCHECK(checkpoints_.count(checkpoint) == 0);
83   auto checkpoint_iter = checkpoints_.emplace(checkpoint, false);
84   return [this, checkpoint_iter] {
85     PERFETTO_DCHECK_THREAD(thread_checker_);
86     checkpoint_iter.first->second = true;
87     if (pending_checkpoint_ == checkpoint_iter.first->first) {
88       pending_checkpoint_.clear();
89       task_runner_.Quit();
90     }
91   };
92 }
93 
94 // TaskRunner implementation.
PostTask(std::function<void ()> closure)95 void TestTaskRunner::PostTask(std::function<void()> closure) {
96   task_runner_.PostTask(std::move(closure));
97 }
98 
PostDelayedTask(std::function<void ()> closure,uint32_t delay_ms)99 void TestTaskRunner::PostDelayedTask(std::function<void()> closure,
100                                      uint32_t delay_ms) {
101   task_runner_.PostDelayedTask(std::move(closure), delay_ms);
102 }
103 
AddFileDescriptorWatch(int fd,std::function<void ()> callback)104 void TestTaskRunner::AddFileDescriptorWatch(int fd,
105                                             std::function<void()> callback) {
106   task_runner_.AddFileDescriptorWatch(fd, std::move(callback));
107 }
108 
RemoveFileDescriptorWatch(int fd)109 void TestTaskRunner::RemoveFileDescriptorWatch(int fd) {
110   task_runner_.RemoveFileDescriptorWatch(fd);
111 }
112 
RunsTasksOnCurrentThread() const113 bool TestTaskRunner::RunsTasksOnCurrentThread() const {
114   return task_runner_.RunsTasksOnCurrentThread();
115 }
116 
117 }  // namespace base
118 }  // namespace perfetto
119