Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 151ab6d

Browse files
committed
Split out the thread data and the thread data set operator
1 parent c32e510 commit 151ab6d

File tree

14 files changed

+295
-272
lines changed

14 files changed

+295
-272
lines changed

fml/concurrent_message_loop.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ ConcurrentMessageLoop::ConcurrentMessageLoop(size_t worker_count)
2121
: worker_count_(std::max<size_t>(worker_count, 1ul)) {
2222
for (size_t i = 0; i < worker_count_; ++i) {
2323
workers_.emplace_back([i, this]() {
24-
fml::Thread::SetCurrentThreadName(
25-
std::string{"io.worker." + std::to_string(i + 1)});
24+
fml::Thread::SetCurrentThreadName(fml::Thread::ThreadConfig(
25+
std::string{"io.worker." + std::to_string(i + 1)}));
2626
WorkerMain();
2727
});
2828
}

fml/thread.cc

Lines changed: 43 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -24,53 +24,6 @@
2424

2525
namespace fml {
2626

27-
Thread::ThreadConfig::ThreadConfig(const std::string& name,
28-
ThreadPriority priority)
29-
: thread_name_(name), thread_priority_(priority) {}
30-
31-
void Thread::ThreadConfig::SetCurrentThreadName() const {
32-
Thread::SetCurrentThreadName(thread_name_);
33-
}
34-
35-
void Thread::ThreadConfig::SetCurrentThreadPriority() const {}
36-
37-
Thread::Thread(const std::string& name)
38-
: Thread(ThreadConfig::MakeDefaultConfigure(name)) {}
39-
40-
Thread::Thread(std::unique_ptr<ThreadConfig> config) : joined_(false) {
41-
fml::AutoResetWaitableEvent latch;
42-
fml::RefPtr<fml::TaskRunner> runner;
43-
thread_ = std::make_unique<std::thread>(
44-
[&latch, &runner, threadConfig = std::move(config)]() -> void {
45-
threadConfig->SetCurrentThreadName();
46-
threadConfig->SetCurrentThreadPriority();
47-
fml::MessageLoop::EnsureInitializedForCurrentThread();
48-
auto& loop = MessageLoop::GetCurrent();
49-
runner = loop.GetTaskRunner();
50-
latch.Signal();
51-
loop.Run();
52-
});
53-
latch.Wait();
54-
task_runner_ = runner;
55-
}
56-
57-
Thread::~Thread() {
58-
Join();
59-
}
60-
61-
fml::RefPtr<fml::TaskRunner> Thread::GetTaskRunner() const {
62-
return task_runner_;
63-
}
64-
65-
void Thread::Join() {
66-
if (joined_) {
67-
return;
68-
}
69-
joined_ = true;
70-
task_runner_->PostTask([]() { MessageLoop::GetCurrent().Terminate(); });
71-
thread_->join();
72-
}
73-
7427
#if defined(FML_OS_WIN)
7528
// The information on how to set the thread name comes from
7629
// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx
@@ -83,7 +36,7 @@ typedef struct tagTHREADNAME_INFO {
8336
} THREADNAME_INFO;
8437
#endif
8538

86-
void Thread::SetCurrentThreadName(const std::string& name) {
39+
void SetThreadName(const std::string& name) {
8740
if (name == "") {
8841
return;
8942
}
@@ -110,4 +63,46 @@ void Thread::SetCurrentThreadName(const std::string& name) {
11063
#endif
11164
}
11265

66+
void Thread::SetCurrentThreadName(const Thread::ThreadConfig& config) {
67+
SetThreadName(config.name);
68+
}
69+
70+
Thread::Thread(const std::string& name)
71+
: Thread(Thread::SetCurrentThreadName, ThreadConfig(name)) {}
72+
73+
Thread::Thread(const ThreadConfigSetter& setter, const ThreadConfig& config)
74+
: joined_(false) {
75+
fml::AutoResetWaitableEvent latch;
76+
fml::RefPtr<fml::TaskRunner> runner;
77+
78+
thread_ = std::make_unique<std::thread>(
79+
[&latch, &runner, setter, config]() -> void {
80+
setter(config);
81+
fml::MessageLoop::EnsureInitializedForCurrentThread();
82+
auto& loop = MessageLoop::GetCurrent();
83+
runner = loop.GetTaskRunner();
84+
latch.Signal();
85+
loop.Run();
86+
});
87+
latch.Wait();
88+
task_runner_ = runner;
89+
}
90+
91+
Thread::~Thread() {
92+
Join();
93+
}
94+
95+
fml::RefPtr<fml::TaskRunner> Thread::GetTaskRunner() const {
96+
return task_runner_;
97+
}
98+
99+
void Thread::Join() {
100+
if (joined_) {
101+
return;
102+
}
103+
joined_ = true;
104+
task_runner_->PostTask([]() { MessageLoop::GetCurrent().Terminate(); });
105+
thread_->join();
106+
}
107+
113108
} // namespace fml

fml/thread.h

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define FLUTTER_FML_THREAD_H_
77

88
#include <atomic>
9+
#include <functional>
910
#include <memory>
1011
#include <string>
1112
#include <thread>
@@ -29,52 +30,40 @@ class Thread {
2930
RASTER,
3031
};
3132

32-
/// The ThreadConfig is used for setting thread perorities.
33-
class ThreadConfig {
34-
public:
35-
explicit ThreadConfig(const std::string& name = "",
36-
ThreadPriority priority = ThreadPriority::NORMAL);
33+
/// The ThreadConfig is the thread info include thread name, thread priority.
34+
struct ThreadConfig {
35+
ThreadConfig(const std::string& name, ThreadPriority priority)
36+
: name(name), priority(priority) {}
3737

38-
static std::unique_ptr<ThreadConfig> MakeDefaultConfigure(
39-
const std::string& name = "") {
40-
return std::make_unique<ThreadConfig>(name);
41-
}
38+
explicit ThreadConfig(const std::string& name)
39+
: ThreadConfig(name, ThreadPriority::NORMAL) {}
4240

43-
ThreadPriority GetThreadPriority() const { return thread_priority_; }
41+
ThreadConfig() : ThreadConfig("", ThreadPriority::NORMAL) {}
4442

45-
const std::string& GetThreadName() const { return thread_name_; }
46-
47-
/// Set current thread name.
48-
virtual void SetCurrentThreadName() const;
49-
50-
/// default do nothing, which mean user can use platform api to set priority
51-
/// example: iOS might use pthread_qos set thread priority, Android might
52-
/// use ::setPriority set thread priority
53-
virtual void SetCurrentThreadPriority() const;
54-
55-
virtual ~ThreadConfig() = default;
56-
57-
private:
58-
const std::string thread_name_;
59-
ThreadPriority thread_priority_;
43+
std::string name;
44+
ThreadPriority priority;
6045
};
6146

62-
explicit Thread(const std::string& name);
47+
using ThreadConfigSetter = std::function<void(const ThreadConfig&)>;
6348

64-
explicit Thread(std::unique_ptr<ThreadConfig> config =
65-
ThreadConfig::MakeDefaultConfigure());
49+
explicit Thread(const std::string& name = "");
50+
51+
explicit Thread(const ThreadConfigSetter& setter,
52+
const ThreadConfig& config = ThreadConfig());
6653

6754
~Thread();
6855

6956
fml::RefPtr<fml::TaskRunner> GetTaskRunner() const;
7057

7158
void Join();
7259

73-
static void SetCurrentThreadName(const std::string& name);
60+
static void SetCurrentThreadName(const ThreadConfig& config);
7461

7562
private:
7663
std::unique_ptr<std::thread> thread_;
64+
7765
fml::RefPtr<fml::TaskRunner> task_runner_;
66+
7867
std::atomic_bool joined_;
7968

8069
FML_DISALLOW_COPY_AND_ASSIGN(Thread);

fml/thread_unittests.cc

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
#include "flutter/fml/thread.h"
66

7-
#define FLUTTER_PTHREAD_SUPPORTED \
8-
defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_ANDROID)
7+
#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_ANDROID)
8+
#define FLUTTER_PTHREAD_SUPPORTED 1
9+
#else
10+
#define FLUTTER_PTHREAD_SUPPORTED 0
11+
#endif
912

10-
#ifdef FLUTTER_PTHREAD_SUPPORTED
13+
#if FLUTTER_PTHREAD_SUPPORTED
1114
#include <pthread.h>
1215
#else
13-
#error "Doesn't has pthead.h"
1416
#endif
1517

1618
#include <memory>
@@ -35,71 +37,70 @@ TEST(Thread, HasARunningMessageLoop) {
3537
ASSERT_TRUE(done);
3638
}
3739

38-
#ifdef FLUTTER_PTHREAD_SUPPORTED
40+
#if FLUTTER_PTHREAD_SUPPORTED
3941
TEST(Thread, ThreadNameCreatedWithConfig) {
4042
const std::string name = "Thread1";
41-
fml::Thread thread(fml::Thread::ThreadConfig::MakeDefaultConfigure(name));
43+
fml::Thread thread(name);
4244

4345
bool done = false;
44-
constexpr int NAMELEN = 8;
4546
thread.GetTaskRunner()->PostTask([&done, &name]() {
4647
done = true;
47-
char thread_name[NAMELEN];
48+
char thread_name[8];
4849
pthread_t current_thread = pthread_self();
49-
pthread_getname_np(current_thread, thread_name, NAMELEN);
50+
pthread_getname_np(current_thread, thread_name, 8);
5051
ASSERT_EQ(thread_name, name);
5152
});
5253
thread.Join();
5354
ASSERT_TRUE(done);
5455
}
5556

56-
class MockThreadConfig : public fml::Thread::ThreadConfig {
57-
public:
58-
using fml::Thread::ThreadConfig::ThreadConfig;
57+
static void MockThreadConfigSetter(const fml::Thread::ThreadConfig& config) {
58+
// set thread name
59+
fml::Thread::SetCurrentThreadName(config);
5960

60-
void SetCurrentThreadPriority() const override {
61-
pthread_t tid = pthread_self();
62-
struct sched_param param;
63-
int policy = SCHED_OTHER;
64-
switch (GetThreadPriority()) {
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);
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;
7270
}
73-
};
71+
pthread_setschedparam(tid, policy, &param);
72+
}
7473

7574
TEST(Thread, ThreadPriorityCreatedWithConfig) {
7675
const std::string thread1_name = "Thread1";
7776
const std::string thread2_name = "Thread2";
78-
fml::Thread thread(std::make_unique<MockThreadConfig>(
79-
thread1_name, fml::Thread::ThreadPriority::NORMAL));
8077

78+
fml::Thread thread(MockThreadConfigSetter,
79+
fml::Thread::ThreadConfig(
80+
thread1_name, fml::Thread::ThreadPriority::NORMAL));
8181
bool done = false;
82-
constexpr int NAMELEN = 8;
82+
8383
struct sched_param param;
8484
int policy;
8585
thread.GetTaskRunner()->PostTask([&]() {
8686
done = true;
87-
char thread_name[NAMELEN];
87+
char thread_name[8];
8888
pthread_t current_thread = pthread_self();
89-
pthread_getname_np(current_thread, thread_name, NAMELEN);
89+
pthread_getname_np(current_thread, thread_name, 8);
9090
pthread_getschedparam(current_thread, &policy, &param);
9191
ASSERT_EQ(thread_name, thread1_name);
9292
ASSERT_EQ(policy, SCHED_OTHER);
9393
ASSERT_EQ(param.sched_priority, 1);
9494
});
9595

96-
fml::Thread thread2(std::make_unique<MockThreadConfig>(
97-
thread2_name, fml::Thread::ThreadPriority::DISPLAY));
96+
fml::Thread thread2(MockThreadConfigSetter,
97+
fml::Thread::ThreadConfig(
98+
thread2_name, fml::Thread::ThreadPriority::DISPLAY));
9899
thread2.GetTaskRunner()->PostTask([&]() {
99100
done = true;
100-
char thread_name[NAMELEN];
101+
char thread_name[8];
101102
pthread_t current_thread = pthread_self();
102-
pthread_getname_np(current_thread, thread_name, NAMELEN);
103+
pthread_getname_np(current_thread, thread_name, 8);
103104
pthread_getschedparam(current_thread, &policy, &param);
104105
ASSERT_EQ(thread_name, thread2_name);
105106
ASSERT_EQ(policy, SCHED_OTHER);

lib/ui/ui_benchmarks.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ class Fixture : public testing::FixtureTest {
2020
};
2121

2222
static void BM_PlatformMessageResponseDartComplete(benchmark::State& state) {
23-
ThreadHost thread_host("test",
24-
ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
25-
ThreadHost::Type::IO | ThreadHost::Type::UI);
23+
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
24+
"test", ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
25+
ThreadHost::Type::IO | ThreadHost::Type::UI));
2626
TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
2727
thread_host.raster_thread->GetTaskRunner(),
2828
thread_host.ui_thread->GetTaskRunner(),
@@ -68,9 +68,9 @@ static void BM_PlatformMessageResponseDartComplete(benchmark::State& state) {
6868
}
6969

7070
static void BM_PathVolatilityTracker(benchmark::State& state) {
71-
ThreadHost thread_host("test",
72-
ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
73-
ThreadHost::Type::IO | ThreadHost::Type::UI);
71+
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
72+
"test", ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
73+
ThreadHost::Type::IO | ThreadHost::Type::UI));
7474
TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
7575
thread_host.raster_thread->GetTaskRunner(),
7676
thread_host.ui_thread->GetTaskRunner(),

shell/common/shell_benchmarks.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ static void StartupAndShutdownShell(benchmark::State& state,
4343
};
4444
}
4545

46-
thread_host = std::make_unique<ThreadHost>(
46+
thread_host = std::make_unique<ThreadHost>(ThreadHost::ThreadHostConfig(
4747
"io.flutter.bench.", ThreadHost::Type::Platform |
4848
ThreadHost::Type::RASTER |
49-
ThreadHost::Type::IO | ThreadHost::Type::UI);
49+
ThreadHost::Type::IO | ThreadHost::Type::UI));
5050

5151
TaskRunners task_runners("test",
5252
thread_host->platform_thread->GetTaskRunner(),

shell/common/shell_unittests.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,10 @@ TEST_F(ShellTest, InitializeWithInvalidThreads) {
264264
TEST_F(ShellTest, InitializeWithDifferentThreads) {
265265
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
266266
Settings settings = CreateSettingsForFixture();
267-
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
268-
ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
269-
ThreadHost::Type::IO | ThreadHost::Type::UI);
267+
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
268+
"io.flutter.test." + GetCurrentTestName() + ".",
269+
ThreadHost::Type::Platform | ThreadHost::Type::RASTER |
270+
ThreadHost::Type::IO | ThreadHost::Type::UI));
270271
TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
271272
thread_host.raster_thread->GetTaskRunner(),
272273
thread_host.ui_thread->GetTaskRunner(),
@@ -3112,8 +3113,9 @@ TEST_F(ShellTest, UpdateAssetResolverByTypeAppends) {
31123113
TEST_F(ShellTest, UpdateAssetResolverByTypeNull) {
31133114
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
31143115
Settings settings = CreateSettingsForFixture();
3115-
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
3116-
ThreadHost::Type::Platform);
3116+
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
3117+
"io.flutter.test." + GetCurrentTestName() + ".",
3118+
ThreadHost::Type::Platform));
31173119
auto task_runner = thread_host.platform_thread->GetTaskRunner();
31183120
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
31193121
task_runner);
@@ -3149,8 +3151,9 @@ TEST_F(ShellTest, UpdateAssetResolverByTypeNull) {
31493151
TEST_F(ShellTest, UpdateAssetResolverByTypeDoesNotReplaceMismatchType) {
31503152
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
31513153
Settings settings = CreateSettingsForFixture();
3152-
ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
3153-
ThreadHost::Type::Platform);
3154+
ThreadHost thread_host(ThreadHost::ThreadHostConfig(
3155+
"io.flutter.test." + GetCurrentTestName() + ".",
3156+
ThreadHost::Type::Platform));
31543157
auto task_runner = thread_host.platform_thread->GetTaskRunner();
31553158
TaskRunners task_runners("test", task_runner, task_runner, task_runner,
31563159
task_runner);

0 commit comments

Comments
 (0)