| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "flutter/fml/thread.h" | |
| #if defined(FML_OS_MACOSX) || defined(FML_OS_LINUX) || defined(FML_OS_ANDROID) | |
| #define FLUTTER_PTHREAD_SUPPORTED 1 | |
| #else | |
| #define FLUTTER_PTHREAD_SUPPORTED 0 | |
| #endif | |
| #if FLUTTER_PTHREAD_SUPPORTED | |
| #include <pthread.h> | |
| #else | |
| #endif | |
| #include <memory> | |
| #include "gtest/gtest.h" | |
| TEST(Thread, CanStartAndEnd) { | |
| fml::Thread thread; | |
| ASSERT_TRUE(thread.GetTaskRunner()); | |
| } | |
| TEST(Thread, CanStartAndEndWithExplicitJoin) { | |
| fml::Thread thread; | |
| ASSERT_TRUE(thread.GetTaskRunner()); | |
| thread.Join(); | |
| } | |
| TEST(Thread, HasARunningMessageLoop) { | |
| fml::Thread thread; | |
| bool done = false; | |
| thread.GetTaskRunner()->PostTask([&done]() { done = true; }); | |
| thread.Join(); | |
| ASSERT_TRUE(done); | |
| } | |
| #if FLUTTER_PTHREAD_SUPPORTED | |
| TEST(Thread, ThreadNameCreatedWithConfig) { | |
| const std::string name = "Thread1"; | |
| fml::Thread thread(name); | |
| bool done = false; | |
| thread.GetTaskRunner()->PostTask([&done, &name]() { | |
| done = true; | |
| char thread_name[8]; | |
| pthread_t current_thread = pthread_self(); | |
| pthread_getname_np(current_thread, thread_name, 8); | |
| ASSERT_EQ(thread_name, name); | |
| }); | |
| thread.Join(); | |
| ASSERT_TRUE(done); | |
| } | |
| static void MockThreadConfigSetter(const fml::Thread::ThreadConfig& config) { | |
| // set thread name | |
| fml::Thread::SetCurrentThreadName(config); | |
| pthread_t tid = pthread_self(); | |
| struct sched_param param; | |
| int policy = SCHED_OTHER; | |
| switch (config.priority) { | |
| case fml::Thread::ThreadPriority::kDisplay: | |
| param.sched_priority = 10; | |
| break; | |
| default: | |
| param.sched_priority = 1; | |
| } | |
| pthread_setschedparam(tid, policy, ¶m); | |
| } | |
| TEST(Thread, ThreadPriorityCreatedWithConfig) { | |
| const std::string thread1_name = "Thread1"; | |
| const std::string thread2_name = "Thread2"; | |
| fml::Thread thread(MockThreadConfigSetter, | |
| fml::Thread::ThreadConfig( | |
| thread1_name, fml::Thread::ThreadPriority::kNormal)); | |
| bool done = false; | |
| struct sched_param param; | |
| int policy; | |
| thread.GetTaskRunner()->PostTask([&]() { | |
| done = true; | |
| char thread_name[8]; | |
| pthread_t current_thread = pthread_self(); | |
| pthread_getname_np(current_thread, thread_name, 8); | |
| pthread_getschedparam(current_thread, &policy, ¶m); | |
| ASSERT_EQ(thread_name, thread1_name); | |
| ASSERT_EQ(policy, SCHED_OTHER); | |
| ASSERT_EQ(param.sched_priority, 1); | |
| }); | |
| fml::Thread thread2(MockThreadConfigSetter, | |
| fml::Thread::ThreadConfig( | |
| thread2_name, fml::Thread::ThreadPriority::kDisplay)); | |
| thread2.GetTaskRunner()->PostTask([&]() { | |
| done = true; | |
| char thread_name[8]; | |
| pthread_t current_thread = pthread_self(); | |
| pthread_getname_np(current_thread, thread_name, 8); | |
| pthread_getschedparam(current_thread, &policy, ¶m); | |
| ASSERT_EQ(thread_name, thread2_name); | |
| ASSERT_EQ(policy, SCHED_OTHER); | |
| ASSERT_EQ(param.sched_priority, 10); | |
| }); | |
| thread.Join(); | |
| ASSERT_TRUE(done); | |
| } | |
| #endif |