Flutter Engine
The 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
17namespace fml {
18namespace testing {
19
20TEST(TaskRunnerCheckerTests, RunsOnCurrentTaskRunner) {
21 TaskRunnerChecker checker;
22 EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
23}
24
25TEST(TaskRunnerCheckerTests, FailsTheCheckIfOnDifferentTaskRunner) {
26 TaskRunnerChecker checker;
27 EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
28 fml::MessageLoop* loop = nullptr;
30 std::thread another_thread([&]() {
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 another_thread.join();
42 EXPECT_EQ(checker.RunsOnCreationTaskRunner(), true);
43}
44
45TEST(TaskRunnerCheckerTests, SameTaskRunnerRunsOnTheSameThread) {
49 TaskQueueId a = loop1.GetTaskRunner()->GetTaskQueueId();
50 TaskQueueId b = loop2.GetTaskRunner()->GetTaskQueueId();
52}
53
54TEST(TaskRunnerCheckerTests, RunsOnDifferentThreadsReturnsFalse) {
57 TaskQueueId a = loop1.GetTaskRunner()->GetTaskQueueId();
59 std::thread another_thread([&]() {
62 TaskQueueId b = loop2.GetTaskRunner()->GetTaskQueueId();
63 EXPECT_EQ(TaskRunnerChecker::RunsOnTheSameThread(a, b), false);
64 latch.Signal();
65 });
66 latch.Wait();
67 another_thread.join();
68}
69
70TEST(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();
93 fml::TaskQueueId qid1 = loop1->GetTaskRunner()->GetTaskQueueId();
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
120TEST(TaskRunnerCheckerTests,
121 PassesRunsOnCreationTaskRunnerIfOnDifferentTaskRunner) {
122 fml::MessageLoop* loop1 = nullptr;
124 std::thread thread1([&]() {
127 latch1.Signal();
128 loop1->Run();
129 });
130
131 fml::MessageLoop* loop2 = nullptr;
133 std::thread thread2([&]() {
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();
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
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
static void loop1(skiatest::Reporter *reporter, const char *filename)
static void loop2(skiatest::Reporter *reporter, const char *filename)
static MessageLoopTaskQueues * GetInstance()
bool Merge(TaskQueueId owner, TaskQueueId subsumed)
bool Unmerge(TaskQueueId owner, TaskQueueId subsumed)
static void EnsureInitializedForCurrentThread()
Definition: message_loop.cc:27
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
Definition: message_loop.cc:56
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
bool RunsOnCreationTaskRunner() const
static bool RunsOnTheSameThread(TaskQueueId queue_a, TaskQueueId queue_b)
virtual void PostTask(const fml::closure &task) override
Definition: task_runner.cc:24
static bool b
struct MyStruct a[10]
TEST(BacktraceTest, CanGatherBacktrace)
Definition: ascii_trie.cc:9