Flutter Engine
task_runner_checker_unittest.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #define FML_USED_ON_EMBEDDER
6 
7 #include "flutter/fml/memory/task_runner_checker.h"
8 
9 #include <thread>
10 
11 #include "flutter/fml/message_loop.h"
12 #include "flutter/fml/raster_thread_merger.h"
13 #include "flutter/fml/synchronization/count_down_latch.h"
14 #include "flutter/fml/synchronization/waitable_event.h"
15 #include "gtest/gtest.h"
16 
17 namespace fml {
18 namespace testing {
19 
20 TEST(TaskRunnerCheckerTests, RunsOnCurrentTaskRunner) {
21  TaskRunnerChecker checker;
22  EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
23 }
24 
25 TEST(TaskRunnerCheckerTests, FailsTheCheckIfOnDifferentTaskRunner) {
26  TaskRunnerChecker checker;
27  EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
28  fml::MessageLoop* loop = nullptr;
30  std::thread anotherThread([&]() {
33  loop->GetTaskRunner()->PostTask([&]() {
34  EXPECT_EQ(checker.RunsOnCreationTaskRunner(), false);
35  latch.Signal();
36  });
37  loop->Run();
38  });
39  latch.Wait();
40  loop->Terminate();
41  anotherThread.join();
42  EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
43 }
44 
45 TEST(TaskRunnerCheckerTests, SameTaskRunnerRunsOnTheSameThread) {
51  EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(a, b), true);
52 }
53 
54 TEST(TaskRunnerCheckerTests, RunsOnDifferentThreadsReturnsFalse) {
59  std::thread anotherThread([&]() {
63  EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(a, b), false);
64  latch.Signal();
65  });
66  latch.Wait();
67  anotherThread.join();
68 }
69 
70 TEST(TaskRunnerCheckerTests, MergedTaskRunnersRunsOnTheSameThread) {
71  fml::MessageLoop* loop1 = nullptr;
74  std::thread thread1([&loop1, &latch1, &term1]() {
77  latch1.Signal();
78  term1.Wait();
79  });
80 
81  fml::MessageLoop* loop2 = nullptr;
84  std::thread thread2([&loop2, &latch2, &term2]() {
87  latch2.Signal();
88  term2.Wait();
89  });
90 
91  latch1.Wait();
92  latch2.Wait();
94  fml::TaskQueueId qid2 = loop2->GetTaskRunner()->GetTaskQueueId();
95  const auto raster_thread_merger_ =
96  fml::MakeRefCounted<fml::RasterThreadMerger>(qid1, qid2);
97  const size_t kNumFramesMerged = 5;
98 
99  raster_thread_merger_->MergeWithLease(kNumFramesMerged);
100 
101  // merged, running on the same thread
102  EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(qid1, qid2), true);
103 
104  for (size_t i = 0; i < kNumFramesMerged; i++) {
105  ASSERT_TRUE(raster_thread_merger_->IsMerged());
106  raster_thread_merger_->DecrementLease();
107  }
108 
109  ASSERT_FALSE(raster_thread_merger_->IsMerged());
110 
111  // un-merged, not running on the same thread
112  EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(qid1, qid2), false);
113 
114  term1.Signal();
115  term2.Signal();
116  thread1.join();
117  thread2.join();
118 }
119 
120 TEST(TaskRunnerCheckerTests,
121  PassesRunsOnCreationTaskRunnerIfOnDifferentTaskRunner) {
122  fml::MessageLoop* loop1 = nullptr;
124  std::thread thread1([&]() {
126  loop1 = &fml::MessageLoop::GetCurrent();
127  latch1.Signal();
128  loop1->Run();
129  });
130 
131  fml::MessageLoop* loop2 = nullptr;
133  std::thread thread2([&]() {
135  loop2 = &fml::MessageLoop::GetCurrent();
136  latch2.Signal();
137  loop2->Run();
138  });
139 
140  latch1.Wait();
141  latch2.Wait();
142 
143  fml::TaskQueueId qid1 = loop1->GetTaskRunner()->GetTaskQueueId();
144  fml::TaskQueueId qid2 = loop2->GetTaskRunner()->GetTaskQueueId();
145  fml::MessageLoopTaskQueues::GetInstance()->Merge(qid1, qid2);
146 
147  std::unique_ptr<TaskRunnerChecker> checker;
148 
150  loop2->GetTaskRunner()->PostTask([&]() {
151  checker = std::make_unique<TaskRunnerChecker>();
152  EXPECT_EQ(checker->RunsOnCreationTaskRunner(), true);
153  latch3.Signal();
154  });
155  latch3.Wait();
156 
157  fml::MessageLoopTaskQueues::GetInstance()->Unmerge(qid1, qid2);
158 
160  loop2->GetTaskRunner()->PostTask([&]() {
161  EXPECT_EQ(checker->RunsOnCreationTaskRunner(), true);
162  latch4.Signal();
163  });
164  latch4.Wait();
165 
166  loop1->Terminate();
167  loop2->Terminate();
168  thread1.join();
169  thread2.join();
170 }
171 
172 } // namespace testing
173 } // namespace fml
virtual TaskQueueId GetTaskQueueId()
Definition: task_runner.cc:38
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
static void EnsureInitializedForCurrentThread()
Definition: message_loop.cc:27
Definition: ascii_trie.cc:9
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
Definition: message_loop.cc:56
TEST(BacktraceTest, CanGatherBacktrace)
static fml::RefPtr< MessageLoopTaskQueues > GetInstance()
bool RunsOnCreationTaskRunner() const
static bool RunsOnTheSameThread(TaskQueueId queue_a, TaskQueueId queue_b)