Flutter Engine
thread.cc
Go to the documentation of this file.
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 
12 #include "flutter/fml/build_config.h"
13 #include "flutter/fml/message_loop.h"
14 #include "flutter/fml/synchronization/waitable_event.h"
15 
16 #if defined(OS_WIN)
17 #include <windows.h>
18 #elif defined(OS_FUCHSIA)
19 #include <lib/zx/thread.h>
20 #else
21 #include <pthread.h>
22 #endif
23 
24 namespace fml {
25 
26 Thread::Thread(const std::string& name) : joined_(false) {
29  thread_ = std::make_unique<std::thread>([&latch, &runner, name]() -> void {
32  auto& loop = MessageLoop::GetCurrent();
33  runner = loop.GetTaskRunner();
34  latch.Signal();
35  loop.Run();
36  });
37  latch.Wait();
38  task_runner_ = runner;
39 }
40 
42  Join();
43 }
44 
46  return task_runner_;
47 }
48 
49 void Thread::Join() {
50  if (joined_) {
51  return;
52  }
53  joined_ = true;
54  task_runner_->PostTask([]() { MessageLoop::GetCurrent().Terminate(); });
55  thread_->join();
56 }
57 
58 #if defined(OS_WIN)
59 // The information on how to set the thread name comes from
60 // a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx
61 const DWORD kVCThreadNameException = 0x406D1388;
62 typedef struct tagTHREADNAME_INFO {
63  DWORD dwType; // Must be 0x1000.
64  LPCSTR szName; // Pointer to name (in user addr space).
65  DWORD dwThreadID; // Thread ID (-1=caller thread).
66  DWORD dwFlags; // Reserved for future use, must be zero.
67 } THREADNAME_INFO;
68 #endif
69 
70 void Thread::SetCurrentThreadName(const std::string& name) {
71  if (name == "") {
72  return;
73  }
74 #if defined(OS_MACOSX)
75  pthread_setname_np(name.c_str());
76 #elif defined(OS_LINUX) || defined(OS_ANDROID)
77  pthread_setname_np(pthread_self(), name.c_str());
78 #elif defined(OS_WIN)
79  THREADNAME_INFO info;
80  info.dwType = 0x1000;
81  info.szName = name.c_str();
82  info.dwThreadID = GetCurrentThreadId();
83  info.dwFlags = 0;
84  __try {
85  RaiseException(kVCThreadNameException, 0, sizeof(info) / sizeof(DWORD),
86  reinterpret_cast<DWORD_PTR*>(&info));
87  } __except (EXCEPTION_CONTINUE_EXECUTION) {
88  }
89 #elif defined(OS_FUCHSIA)
90  zx::thread::self()->set_property(ZX_PROP_NAME, name.c_str(), name.size());
91 #else
92  FML_DLOG(INFO) << "Could not set the thread name to '" << name
93  << "' on this platform.";
94 #endif
95 }
96 
97 } // namespace fml
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
Definition: thread.cc:45
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
Definition: message_loop.cc:19
virtual void PostTask(const fml::closure &task)
Definition: task_runner.cc:24
static void EnsureInitializedForCurrentThread()
Definition: message_loop.cc:27
Definition: ascii_trie.cc:9
const char * name
Definition: fuchsia.cc:50
static void SetCurrentThreadName(const std::string &name)
Definition: thread.cc:70
void Join()
Definition: thread.cc:49
#define FML_DLOG(severity)
Definition: logging.h:85
Thread(const std::string &name="")
Definition: thread.cc:26