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#include "flutter/fml/thread.h"
6
7#if defined(FML_OS_MACOSX) || defined(FML_OS_LINUX) || defined(FML_OS_ANDROID)
8#define FLUTTER_PTHREAD_SUPPORTED 1
9#else
10#define FLUTTER_PTHREAD_SUPPORTED 0
11#endif
12
13#if FLUTTER_PTHREAD_SUPPORTED
14#include <pthread.h>
15#else
16#endif
17
18#include <memory>
19#include "gtest/gtest.h"
20
21TEST(Thread, CanStartAndEnd) {
22 fml::Thread thread;
23 ASSERT_TRUE(thread.GetTaskRunner());
24}
25
26TEST(Thread, CanStartAndEndWithExplicitJoin) {
27 fml::Thread thread;
28 ASSERT_TRUE(thread.GetTaskRunner());
29 thread.Join();
30}
31
32TEST(Thread, HasARunningMessageLoop) {
33 fml::Thread thread;
34 bool done = false;
35 thread.GetTaskRunner()->PostTask(task: [&done]() { done = true; });
36 thread.Join();
37 ASSERT_TRUE(done);
38}
39
40#if FLUTTER_PTHREAD_SUPPORTED
41TEST(Thread, ThreadNameCreatedWithConfig) {
42 const std::string name = "Thread1";
43 fml::Thread thread(name);
44
45 bool done = false;
46 thread.GetTaskRunner()->PostTask([&done, &name]() {
47 done = true;
48 char thread_name[8];
49 pthread_t current_thread = pthread_self();
50 pthread_getname_np(current_thread, thread_name, 8);
51 ASSERT_EQ(thread_name, name);
52 });
53 thread.Join();
54 ASSERT_TRUE(done);
55}
56
57static void MockThreadConfigSetter(const fml::Thread::ThreadConfig& config) {
58 // set thread name
59 fml::Thread::SetCurrentThreadName(config);
60
61 pthread_t tid = pthread_self();
62 struct sched_param param;
63 int policy = SCHED_OTHER;
64 switch (config.priority) {
65 case fml::Thread::ThreadPriority::DISPLAY:
66 param.sched_priority = 10;
67 break;
68 default:
69 param.sched_priority = 1;
70 }
71 pthread_setschedparam(tid, policy, &param);
72}
73
74TEST(Thread, ThreadPriorityCreatedWithConfig) {
75 const std::string thread1_name = "Thread1";
76 const std::string thread2_name = "Thread2";
77
78 fml::Thread thread(MockThreadConfigSetter,
79 fml::Thread::ThreadConfig(
80 thread1_name, fml::Thread::ThreadPriority::NORMAL));
81 bool done = false;
82
83 struct sched_param param;
84 int policy;
85 thread.GetTaskRunner()->PostTask([&]() {
86 done = true;
87 char thread_name[8];
88 pthread_t current_thread = pthread_self();
89 pthread_getname_np(current_thread, thread_name, 8);
90 pthread_getschedparam(current_thread, &policy, &param);
91 ASSERT_EQ(thread_name, thread1_name);
92 ASSERT_EQ(policy, SCHED_OTHER);
93 ASSERT_EQ(param.sched_priority, 1);
94 });
95
96 fml::Thread thread2(MockThreadConfigSetter,
97 fml::Thread::ThreadConfig(
98 thread2_name, fml::Thread::ThreadPriority::DISPLAY));
99 thread2.GetTaskRunner()->PostTask([&]() {
100 done = true;
101 char thread_name[8];
102 pthread_t current_thread = pthread_self();
103 pthread_getname_np(current_thread, thread_name, 8);
104 pthread_getschedparam(current_thread, &policy, &param);
105 ASSERT_EQ(thread_name, thread2_name);
106 ASSERT_EQ(policy, SCHED_OTHER);
107 ASSERT_EQ(param.sched_priority, 10);
108 });
109 thread.Join();
110 ASSERT_TRUE(done);
111}
112#endif
113

source code of flutter_engine/flutter/fml/thread_unittests.cc