5#define FML_USED_ON_EMBEDDER
7#include "flutter/fml/message_loop.h"
12#include "flutter/fml/build_config.h"
13#include "flutter/fml/concurrent_message_loop.h"
14#include "flutter/fml/synchronization/count_down_latch.h"
15#include "flutter/fml/synchronization/waitable_event.h"
16#include "flutter/fml/task_runner.h"
17#include "flutter/fml/time/chrono_timestamp_provider.h"
18#include "gtest/gtest.h"
20TEST(MessageLoop, GetCurrent) {
21 std::thread thread([]() {
28TEST(MessageLoop, DifferentThreadsHaveDifferentLoops) {
32 std::thread thread1([&
loop1, &latch1, &term1]() {
42 std::thread thread2([&
loop2, &latch2, &term2]() {
57TEST(MessageLoop, CanRunAndTerminate) {
59 bool terminated =
false;
60 std::thread thread([&started, &terminated]() {
63 ASSERT_TRUE(loop.GetTaskRunner());
64 loop.GetTaskRunner()->PostTask([&terminated]() {
73 ASSERT_TRUE(terminated);
76TEST(MessageLoop, NonDelayedTasksAreRunInOrder) {
77 const size_t count = 100;
79 bool terminated =
false;
80 std::thread thread([&started, &terminated,
count]() {
85 loop.GetTaskRunner()->PostTask([&terminated,
i, ¤t]() {
86 ASSERT_EQ(current,
i);
95 ASSERT_EQ(current,
count);
100 ASSERT_TRUE(terminated);
103TEST(MessageLoop, DelayedTasksAtSameTimeAreRunInOrder) {
104 const size_t count = 100;
105 bool started =
false;
106 bool terminated =
false;
107 std::thread thread([&started, &terminated,
count]() {
111 const auto now_plus_some =
113 for (
size_t i = 0;
i <
count;
i++) {
114 loop.GetTaskRunner()->PostTaskForTime(
115 [&terminated,
i, ¤t]() {
116 ASSERT_EQ(current,
i);
126 ASSERT_EQ(current,
count);
130 ASSERT_TRUE(started);
131 ASSERT_TRUE(terminated);
134TEST(MessageLoop, CheckRunsTaskOnCurrentThread) {
137 std::thread thread([&runner, &latch]() {
140 runner = loop.GetTaskRunner();
142 ASSERT_TRUE(loop.GetTaskRunner()->RunsTasksOnCurrentThread());
150TEST(MessageLoop, TaskObserverFire) {
151 bool started =
false;
152 bool terminated =
false;
153 std::thread thread([&started, &terminated]() {
155 const size_t count = 25;
157 size_t task_count = 0;
158 size_t obs_count = 0;
159 auto obs = [&obs_count]() { obs_count++; };
160 for (
size_t i = 0;
i <
count;
i++) {
161 loop.GetTaskRunner()->PostTask([&terminated,
i, &task_count]() {
162 ASSERT_EQ(task_count,
i);
170 loop.AddTaskObserver(0, obs);
172 ASSERT_EQ(task_count,
count);
173 ASSERT_EQ(obs_count,
count);
177 ASSERT_TRUE(started);
178 ASSERT_TRUE(terminated);
181TEST(MessageLoop, ConcurrentMessageLoopHasNonZeroWorkers) {
184 ASSERT_GT(loop->GetWorkerCount(), 0u);
187TEST(MessageLoop, CanCreateAndShutdownConcurrentMessageLoopsOverAndOver) {
188 for (
size_t i = 0;
i < 10; ++
i) {
190 ASSERT_EQ(loop->GetWorkerCount(),
i + 1);
194TEST(MessageLoop, CanCreateConcurrentMessageLoop) {
196 auto task_runner = loop->GetTaskRunner();
197 const size_t kCount = 10;
199 std::mutex thread_ids_mutex;
200 std::set<std::thread::id> thread_ids;
201 for (
size_t i = 0;
i < kCount; ++
i) {
202 task_runner->PostTask([&]() {
203 std::this_thread::sleep_for(std::chrono::seconds(1));
204 std::cout <<
"Ran on thread: " << std::this_thread::get_id() << std::endl;
206 std::scoped_lock lock(thread_ids_mutex);
207 thread_ids.insert(std::this_thread::get_id());
213 ASSERT_GE(thread_ids.size(), 1u);
static void loop1(skiatest::Reporter *reporter, const char *filename)
static void loop2(skiatest::Reporter *reporter, const char *filename)
static std::shared_ptr< ConcurrentMessageLoop > Create(size_t worker_count=std::thread::hardware_concurrency())
static void EnsureInitializedForCurrentThread()
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
virtual bool RunsTasksOnCurrentThread()
static constexpr TimeDelta FromMilliseconds(int64_t millis)
TEST(MessageLoop, GetCurrent)
fml::TimePoint ChronoTicksSinceEpoch()