xref: /aosp_15_r20/external/perfetto/src/base/task_runner_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/build_config.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/unix_task_runner.h"
20*6dbdd20aSAndroid Build Coastguard Worker 
21*6dbdd20aSAndroid Build Coastguard Worker #include <thread>
22*6dbdd20aSAndroid Build Coastguard Worker 
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/event_fd.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/file_utils.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/pipe.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/scoped_file.h"
27*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/utils.h"
28*6dbdd20aSAndroid Build Coastguard Worker #include "test/gtest_and_gmock.h"
29*6dbdd20aSAndroid Build Coastguard Worker 
30*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
31*6dbdd20aSAndroid Build Coastguard Worker namespace base {
32*6dbdd20aSAndroid Build Coastguard Worker namespace {
33*6dbdd20aSAndroid Build Coastguard Worker 
34*6dbdd20aSAndroid Build Coastguard Worker class TaskRunnerTest : public ::testing::Test {
35*6dbdd20aSAndroid Build Coastguard Worker  public:
36*6dbdd20aSAndroid Build Coastguard Worker   UnixTaskRunner task_runner;
37*6dbdd20aSAndroid Build Coastguard Worker };
38*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,PostImmediateTask)39*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, PostImmediateTask) {
40*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
41*6dbdd20aSAndroid Build Coastguard Worker   int counter = 0;
42*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&counter] { counter = (counter << 4) | 1; });
43*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&counter] { counter = (counter << 4) | 2; });
44*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&counter] { counter = (counter << 4) | 3; });
45*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&counter] { counter = (counter << 4) | 4; });
46*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&task_runner] { task_runner.Quit(); });
47*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
48*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0x1234, counter);
49*6dbdd20aSAndroid Build Coastguard Worker }
50*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,PostDelayedTask)51*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, PostDelayedTask) {
52*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
53*6dbdd20aSAndroid Build Coastguard Worker   int counter = 0;
54*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 1; }, 5);
55*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 2; }, 10);
56*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 3; }, 15);
57*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 4; }, 15);
58*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 20);
59*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
60*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0x1234, counter);
61*6dbdd20aSAndroid Build Coastguard Worker }
62*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,PostImmediateTaskFromTask)63*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, PostImmediateTaskFromTask) {
64*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
65*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&task_runner] {
66*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostTask([&task_runner] { task_runner.Quit(); });
67*6dbdd20aSAndroid Build Coastguard Worker   });
68*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
69*6dbdd20aSAndroid Build Coastguard Worker }
70*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,PostDelayedTaskFromTask)71*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, PostDelayedTaskFromTask) {
72*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
73*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&task_runner] {
74*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
75*6dbdd20aSAndroid Build Coastguard Worker   });
76*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
77*6dbdd20aSAndroid Build Coastguard Worker }
78*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,PostImmediateTaskFromOtherThread)79*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, PostImmediateTaskFromOtherThread) {
80*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
81*6dbdd20aSAndroid Build Coastguard Worker   ThreadChecker thread_checker;
82*6dbdd20aSAndroid Build Coastguard Worker   int counter = 0;
83*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&task_runner, &counter, &thread_checker] {
84*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostTask([&thread_checker] {
85*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(thread_checker.CalledOnValidThread());
86*6dbdd20aSAndroid Build Coastguard Worker     });
87*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostTask([&counter] { counter = (counter << 4) | 1; });
88*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostTask([&counter] { counter = (counter << 4) | 2; });
89*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostTask([&counter] { counter = (counter << 4) | 3; });
90*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostTask([&counter] { counter = (counter << 4) | 4; });
91*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostTask([&task_runner] { task_runner.Quit(); });
92*6dbdd20aSAndroid Build Coastguard Worker   });
93*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
94*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
95*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0x1234, counter);
96*6dbdd20aSAndroid Build Coastguard Worker }
97*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,PostDelayedTaskFromOtherThread)98*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, PostDelayedTaskFromOtherThread) {
99*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
100*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&task_runner] {
101*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
102*6dbdd20aSAndroid Build Coastguard Worker   });
103*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
104*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
105*6dbdd20aSAndroid Build Coastguard Worker }
106*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,AddFileDescriptorWatch)107*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, AddFileDescriptorWatch) {
108*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
109*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
110*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(),
111*6dbdd20aSAndroid Build Coastguard Worker                                      [&task_runner] { task_runner.Quit(); });
112*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
113*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
114*6dbdd20aSAndroid Build Coastguard Worker }
115*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,RemoveFileDescriptorWatch)116*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, RemoveFileDescriptorWatch) {
117*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
118*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
119*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
120*6dbdd20aSAndroid Build Coastguard Worker 
121*6dbdd20aSAndroid Build Coastguard Worker   bool watch_ran = false;
122*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(),
123*6dbdd20aSAndroid Build Coastguard Worker                                      [&watch_ran] { watch_ran = true; });
124*6dbdd20aSAndroid Build Coastguard Worker   task_runner.RemoveFileDescriptorWatch(evt.fd());
125*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
126*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
127*6dbdd20aSAndroid Build Coastguard Worker 
128*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(watch_ran);
129*6dbdd20aSAndroid Build Coastguard Worker }
130*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,RemoveFileDescriptorWatchFromTask)131*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, RemoveFileDescriptorWatchFromTask) {
132*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
133*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
134*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
135*6dbdd20aSAndroid Build Coastguard Worker 
136*6dbdd20aSAndroid Build Coastguard Worker   bool watch_ran = false;
137*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&task_runner, &evt] {
138*6dbdd20aSAndroid Build Coastguard Worker     task_runner.RemoveFileDescriptorWatch(evt.fd());
139*6dbdd20aSAndroid Build Coastguard Worker   });
140*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(),
141*6dbdd20aSAndroid Build Coastguard Worker                                      [&watch_ran] { watch_ran = true; });
142*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
143*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
144*6dbdd20aSAndroid Build Coastguard Worker 
145*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(watch_ran);
146*6dbdd20aSAndroid Build Coastguard Worker }
147*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,AddFileDescriptorWatchFromAnotherWatch)148*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, AddFileDescriptorWatchFromAnotherWatch) {
149*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
150*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
151*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt2;
152*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
153*6dbdd20aSAndroid Build Coastguard Worker   evt2.Notify();
154*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(), [&task_runner, &evt, &evt2] {
155*6dbdd20aSAndroid Build Coastguard Worker     evt.Clear();
156*6dbdd20aSAndroid Build Coastguard Worker     task_runner.AddFileDescriptorWatch(evt2.fd(),
157*6dbdd20aSAndroid Build Coastguard Worker                                        [&task_runner] { task_runner.Quit(); });
158*6dbdd20aSAndroid Build Coastguard Worker   });
159*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
160*6dbdd20aSAndroid Build Coastguard Worker }
161*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,RemoveFileDescriptorWatchFromAnotherWatch)162*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, RemoveFileDescriptorWatchFromAnotherWatch) {
163*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
164*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
165*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt2;
166*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
167*6dbdd20aSAndroid Build Coastguard Worker 
168*6dbdd20aSAndroid Build Coastguard Worker   bool watch_ran = false;
169*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(), [&task_runner, &evt, &evt2] {
170*6dbdd20aSAndroid Build Coastguard Worker     evt.Clear();
171*6dbdd20aSAndroid Build Coastguard Worker     evt2.Notify();
172*6dbdd20aSAndroid Build Coastguard Worker     task_runner.RemoveFileDescriptorWatch(evt2.fd());
173*6dbdd20aSAndroid Build Coastguard Worker   });
174*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt2.fd(),
175*6dbdd20aSAndroid Build Coastguard Worker                                      [&watch_ran] { watch_ran = true; });
176*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
177*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
178*6dbdd20aSAndroid Build Coastguard Worker 
179*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(watch_ran);
180*6dbdd20aSAndroid Build Coastguard Worker }
181*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,ReplaceFileDescriptorWatchFromAnotherWatch)182*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, ReplaceFileDescriptorWatchFromAnotherWatch) {
183*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
184*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
185*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt2;
186*6dbdd20aSAndroid Build Coastguard Worker 
187*6dbdd20aSAndroid Build Coastguard Worker   bool watch_ran = false;
188*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
189*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(), [&task_runner, &evt, &evt2] {
190*6dbdd20aSAndroid Build Coastguard Worker     evt.Clear();
191*6dbdd20aSAndroid Build Coastguard Worker     evt2.Notify();
192*6dbdd20aSAndroid Build Coastguard Worker     task_runner.RemoveFileDescriptorWatch(evt2.fd());
193*6dbdd20aSAndroid Build Coastguard Worker     task_runner.AddFileDescriptorWatch(evt2.fd(),
194*6dbdd20aSAndroid Build Coastguard Worker                                        [&task_runner] { task_runner.Quit(); });
195*6dbdd20aSAndroid Build Coastguard Worker   });
196*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt2.fd(),
197*6dbdd20aSAndroid Build Coastguard Worker                                      [&watch_ran] { watch_ran = true; });
198*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
199*6dbdd20aSAndroid Build Coastguard Worker 
200*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(watch_ran);
201*6dbdd20aSAndroid Build Coastguard Worker }
202*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,AddFileDescriptorWatchFromAnotherThread)203*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, AddFileDescriptorWatchFromAnotherThread) {
204*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
205*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
206*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
207*6dbdd20aSAndroid Build Coastguard Worker 
208*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&task_runner, &evt] {
209*6dbdd20aSAndroid Build Coastguard Worker     task_runner.AddFileDescriptorWatch(evt.fd(),
210*6dbdd20aSAndroid Build Coastguard Worker                                        [&task_runner] { task_runner.Quit(); });
211*6dbdd20aSAndroid Build Coastguard Worker   });
212*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
213*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
214*6dbdd20aSAndroid Build Coastguard Worker }
215*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,FileDescriptorWatchWithMultipleEvents)216*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, FileDescriptorWatchWithMultipleEvents) {
217*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
218*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
219*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
220*6dbdd20aSAndroid Build Coastguard Worker 
221*6dbdd20aSAndroid Build Coastguard Worker   int event_count = 0;
222*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(
223*6dbdd20aSAndroid Build Coastguard Worker       evt.fd(), [&task_runner, &evt, &event_count] {
224*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_LT(event_count, 3);
225*6dbdd20aSAndroid Build Coastguard Worker         if (++event_count == 3) {
226*6dbdd20aSAndroid Build Coastguard Worker           task_runner.Quit();
227*6dbdd20aSAndroid Build Coastguard Worker           return;
228*6dbdd20aSAndroid Build Coastguard Worker         }
229*6dbdd20aSAndroid Build Coastguard Worker         evt.Clear();
230*6dbdd20aSAndroid Build Coastguard Worker         task_runner.PostTask([&evt] { evt.Notify(); });
231*6dbdd20aSAndroid Build Coastguard Worker       });
232*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
233*6dbdd20aSAndroid Build Coastguard Worker }
234*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,PostManyDelayedTasks)235*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, PostManyDelayedTasks) {
236*6dbdd20aSAndroid Build Coastguard Worker   // Check that PostTask doesn't start failing if there are too many scheduled
237*6dbdd20aSAndroid Build Coastguard Worker   // wake-ups.
238*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
239*6dbdd20aSAndroid Build Coastguard Worker   for (int i = 0; i < 0x1000; i++)
240*6dbdd20aSAndroid Build Coastguard Worker     task_runner.PostDelayedTask([] {}, 0);
241*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
242*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
243*6dbdd20aSAndroid Build Coastguard Worker }
244*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,RunAgain)245*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, RunAgain) {
246*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
247*6dbdd20aSAndroid Build Coastguard Worker   int counter = 0;
248*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&task_runner, &counter] {
249*6dbdd20aSAndroid Build Coastguard Worker     counter++;
250*6dbdd20aSAndroid Build Coastguard Worker     task_runner.Quit();
251*6dbdd20aSAndroid Build Coastguard Worker   });
252*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
253*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&task_runner, &counter] {
254*6dbdd20aSAndroid Build Coastguard Worker     counter++;
255*6dbdd20aSAndroid Build Coastguard Worker     task_runner.Quit();
256*6dbdd20aSAndroid Build Coastguard Worker   });
257*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
258*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(2, counter);
259*6dbdd20aSAndroid Build Coastguard Worker }
260*6dbdd20aSAndroid Build Coastguard Worker 
RepeatingTask(UnixTaskRunner * task_runner)261*6dbdd20aSAndroid Build Coastguard Worker void RepeatingTask(UnixTaskRunner* task_runner) {
262*6dbdd20aSAndroid Build Coastguard Worker   task_runner->PostTask(std::bind(&RepeatingTask, task_runner));
263*6dbdd20aSAndroid Build Coastguard Worker }
264*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,FileDescriptorWatchesNotStarved)265*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, FileDescriptorWatchesNotStarved) {
266*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
267*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
268*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
269*6dbdd20aSAndroid Build Coastguard Worker 
270*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask(std::bind(&RepeatingTask, &task_runner));
271*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(),
272*6dbdd20aSAndroid Build Coastguard Worker                                      [&task_runner] { task_runner.Quit(); });
273*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
274*6dbdd20aSAndroid Build Coastguard Worker }
275*6dbdd20aSAndroid Build Coastguard Worker 
CountdownTask(UnixTaskRunner * task_runner,int * counter)276*6dbdd20aSAndroid Build Coastguard Worker void CountdownTask(UnixTaskRunner* task_runner, int* counter) {
277*6dbdd20aSAndroid Build Coastguard Worker   if (!--(*counter)) {
278*6dbdd20aSAndroid Build Coastguard Worker     task_runner->Quit();
279*6dbdd20aSAndroid Build Coastguard Worker     return;
280*6dbdd20aSAndroid Build Coastguard Worker   }
281*6dbdd20aSAndroid Build Coastguard Worker   task_runner->PostDelayedTask(std::bind(&CountdownTask, task_runner, counter),
282*6dbdd20aSAndroid Build Coastguard Worker                                1);
283*6dbdd20aSAndroid Build Coastguard Worker }
284*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,NoDuplicateFileDescriptorWatchCallbacks)285*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, NoDuplicateFileDescriptorWatchCallbacks) {
286*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
287*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
288*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
289*6dbdd20aSAndroid Build Coastguard Worker 
290*6dbdd20aSAndroid Build Coastguard Worker   bool watch_called = 0;
291*6dbdd20aSAndroid Build Coastguard Worker   int counter = 10;
292*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(), [&evt, &watch_called] {
293*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_FALSE(watch_called);
294*6dbdd20aSAndroid Build Coastguard Worker     evt.Clear();
295*6dbdd20aSAndroid Build Coastguard Worker     watch_called = true;
296*6dbdd20aSAndroid Build Coastguard Worker   });
297*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask(std::bind(&CountdownTask, &task_runner, &counter));
298*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
299*6dbdd20aSAndroid Build Coastguard Worker }
300*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,ReplaceFileDescriptorWatchFromOtherThread)301*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, ReplaceFileDescriptorWatchFromOtherThread) {
302*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
303*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt;
304*6dbdd20aSAndroid Build Coastguard Worker   evt.Notify();
305*6dbdd20aSAndroid Build Coastguard Worker 
306*6dbdd20aSAndroid Build Coastguard Worker   // The two watch tasks here race each other. We don't particularly care which
307*6dbdd20aSAndroid Build Coastguard Worker   // wins as long as one of them runs.
308*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(evt.fd(),
309*6dbdd20aSAndroid Build Coastguard Worker                                      [&task_runner] { task_runner.Quit(); });
310*6dbdd20aSAndroid Build Coastguard Worker 
311*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&task_runner, &evt] {
312*6dbdd20aSAndroid Build Coastguard Worker     task_runner.RemoveFileDescriptorWatch(evt.fd());
313*6dbdd20aSAndroid Build Coastguard Worker     task_runner.AddFileDescriptorWatch(evt.fd(),
314*6dbdd20aSAndroid Build Coastguard Worker                                        [&task_runner] { task_runner.Quit(); });
315*6dbdd20aSAndroid Build Coastguard Worker   });
316*6dbdd20aSAndroid Build Coastguard Worker 
317*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
318*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
319*6dbdd20aSAndroid Build Coastguard Worker }
320*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,IsIdleForTesting)321*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, IsIdleForTesting) {
322*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
323*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask(
324*6dbdd20aSAndroid Build Coastguard Worker       [&task_runner] { EXPECT_FALSE(task_runner.IsIdleForTesting()); });
325*6dbdd20aSAndroid Build Coastguard Worker   task_runner.PostTask([&task_runner] {
326*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(task_runner.IsIdleForTesting());
327*6dbdd20aSAndroid Build Coastguard Worker     task_runner.Quit();
328*6dbdd20aSAndroid Build Coastguard Worker   });
329*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
330*6dbdd20aSAndroid Build Coastguard Worker }
331*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,RunsTasksOnCurrentThread)332*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, RunsTasksOnCurrentThread) {
333*6dbdd20aSAndroid Build Coastguard Worker   auto& main_tr = this->task_runner;
334*6dbdd20aSAndroid Build Coastguard Worker 
335*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(main_tr.RunsTasksOnCurrentThread());
336*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&main_tr] {
337*6dbdd20aSAndroid Build Coastguard Worker     typename std::remove_reference<decltype(main_tr)>::type second_tr;
338*6dbdd20aSAndroid Build Coastguard Worker     second_tr.PostTask([&main_tr, &second_tr] {
339*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(main_tr.RunsTasksOnCurrentThread());
340*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(second_tr.RunsTasksOnCurrentThread());
341*6dbdd20aSAndroid Build Coastguard Worker       second_tr.Quit();
342*6dbdd20aSAndroid Build Coastguard Worker     });
343*6dbdd20aSAndroid Build Coastguard Worker     second_tr.Run();
344*6dbdd20aSAndroid Build Coastguard Worker   });
345*6dbdd20aSAndroid Build Coastguard Worker   main_tr.PostTask([&]() { main_tr.Quit(); });
346*6dbdd20aSAndroid Build Coastguard Worker   main_tr.Run();
347*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
348*6dbdd20aSAndroid Build Coastguard Worker }
349*6dbdd20aSAndroid Build Coastguard Worker 
TEST_F(TaskRunnerTest,FileDescriptorWatchFairness)350*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, FileDescriptorWatchFairness) {
351*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
352*6dbdd20aSAndroid Build Coastguard Worker   EventFd evt[5];
353*6dbdd20aSAndroid Build Coastguard Worker   std::map<PlatformHandle, int /*num_tasks*/> num_tasks;
354*6dbdd20aSAndroid Build Coastguard Worker   static constexpr int kNumTasksPerHandle = 100;
355*6dbdd20aSAndroid Build Coastguard Worker   for (auto& e : evt) {
356*6dbdd20aSAndroid Build Coastguard Worker     e.Notify();
357*6dbdd20aSAndroid Build Coastguard Worker     task_runner.AddFileDescriptorWatch(e.fd(), [&] {
358*6dbdd20aSAndroid Build Coastguard Worker       if (++num_tasks[e.fd()] == kNumTasksPerHandle) {
359*6dbdd20aSAndroid Build Coastguard Worker         e.Clear();
360*6dbdd20aSAndroid Build Coastguard Worker         task_runner.Quit();
361*6dbdd20aSAndroid Build Coastguard Worker       }
362*6dbdd20aSAndroid Build Coastguard Worker     });
363*6dbdd20aSAndroid Build Coastguard Worker   }
364*6dbdd20aSAndroid Build Coastguard Worker 
365*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
366*6dbdd20aSAndroid Build Coastguard Worker 
367*6dbdd20aSAndroid Build Coastguard Worker   // The sequence evt[0], evt[1], evt[2] should be repeated N times. On the
368*6dbdd20aSAndroid Build Coastguard Worker   // Nth time the task runner quits. All tasks should have been running at least
369*6dbdd20aSAndroid Build Coastguard Worker   // N-1 times (we can't predict which one of the tasks will quit).
370*6dbdd20aSAndroid Build Coastguard Worker   for (auto& e : evt) {
371*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_GE(num_tasks[e.fd()], kNumTasksPerHandle - 1);
372*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_LE(num_tasks[e.fd()], kNumTasksPerHandle);
373*6dbdd20aSAndroid Build Coastguard Worker   }
374*6dbdd20aSAndroid Build Coastguard Worker }
375*6dbdd20aSAndroid Build Coastguard Worker 
376*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
377*6dbdd20aSAndroid Build Coastguard Worker 
378*6dbdd20aSAndroid Build Coastguard Worker // This tests UNIX-specific behavior on pipe closure.
TEST_F(TaskRunnerTest,FileDescriptorClosedEvent)379*6dbdd20aSAndroid Build Coastguard Worker TEST_F(TaskRunnerTest, FileDescriptorClosedEvent) {
380*6dbdd20aSAndroid Build Coastguard Worker   auto& task_runner = this->task_runner;
381*6dbdd20aSAndroid Build Coastguard Worker   Pipe pipe = Pipe::Create();
382*6dbdd20aSAndroid Build Coastguard Worker   pipe.wr.reset();
383*6dbdd20aSAndroid Build Coastguard Worker   task_runner.AddFileDescriptorWatch(pipe.rd.get(),
384*6dbdd20aSAndroid Build Coastguard Worker                                      [&task_runner] { task_runner.Quit(); });
385*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
386*6dbdd20aSAndroid Build Coastguard Worker }
387*6dbdd20aSAndroid Build Coastguard Worker 
388*6dbdd20aSAndroid Build Coastguard Worker #endif
389*6dbdd20aSAndroid Build Coastguard Worker 
390*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
391*6dbdd20aSAndroid Build Coastguard Worker }  // namespace base
392*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
393