[go: up one dir, main page]

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/thread.h"
8
9#include <memory>
10#include <string>
11#include <utility>
12
13#include "flutter/fml/build_config.h"
14#include "flutter/fml/message_loop.h"
15#include "flutter/fml/synchronization/waitable_event.h"
16
17#if defined(FML_OS_WIN)
18#include <windows.h>
19#elif defined(OS_FUCHSIA)
20#include <lib/zx/thread.h>
21#else
22#include <pthread.h>
23#endif
24
25namespace fml {
26
27#if defined(FML_OS_WIN)
28// The information on how to set the thread name comes from
29// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx
30const DWORD kVCThreadNameException = 0x406D1388;
31typedef struct tagTHREADNAME_INFO {
32 DWORD dwType; // Must be 0x1000.
33 LPCSTR szName; // Pointer to name (in user addr space).
34 DWORD dwThreadID; // Thread ID (-1=caller thread).
35 DWORD dwFlags; // Reserved for future use, must be zero.
36} THREADNAME_INFO;
37#endif
38
39void SetThreadName(const std::string& name) {
40 if (name == "") {
41 return;
42 }
43#if defined(FML_OS_MACOSX)
44 pthread_setname_np(name.c_str());
45#elif defined(FML_OS_LINUX) || defined(FML_OS_ANDROID)
46 pthread_setname_np(target_thread: pthread_self(), name: name.c_str());
47#elif defined(FML_OS_WIN)
48 THREADNAME_INFO info;
49 info.dwType = 0x1000;
50 info.szName = name.c_str();
51 info.dwThreadID = GetCurrentThreadId();
52 info.dwFlags = 0;
53 __try {
54 RaiseException(kVCThreadNameException, 0, sizeof(info) / sizeof(DWORD),
55 reinterpret_cast<DWORD_PTR*>(&info));
56 } __except (EXCEPTION_CONTINUE_EXECUTION) {
57 }
58#elif defined(OS_FUCHSIA)
59 zx::thread::self()->set_property(ZX_PROP_NAME, name.c_str(), name.size());
60#else
61 FML_DLOG(INFO) << "Could not set the thread name to '" << name
62 << "' on this platform.";
63#endif
64}
65
66void Thread::SetCurrentThreadName(const Thread::ThreadConfig& config) {
67 SetThreadName(config.name);
68}
69
70Thread::Thread(const std::string& name)
71 : Thread(Thread::SetCurrentThreadName, ThreadConfig(name)) {}
72
73Thread::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 args: [&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
91Thread::~Thread() {
92 Join();
93}
94
95fml::RefPtr<fml::TaskRunner> Thread::GetTaskRunner() const {
96 return task_runner_;
97}
98
99void Thread::Join() {
100 if (joined_) {
101 return;
102 }
103 joined_ = true;
104 task_runner_->PostTask(task: []() { MessageLoop::GetCurrent().Terminate(); });
105 thread_->join();
106}
107
108} // namespace fml
109

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