Cuberite
A lightweight, fast and extensible game server for Minecraft
IsThread.cpp
Go to the documentation of this file.
1 
2 // IsThread.cpp
3 
4 // Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread.
5 
6 #include "Globals.h"
7 #include "IsThread.h"
8 
9 
10 
11 
12 
14 // cIsThread:
15 
16 cIsThread::cIsThread(AString && a_ThreadName) :
17  m_ShouldTerminate(false),
18  m_ThreadName(std::move(a_ThreadName))
19 {
20 }
21 
22 
23 
24 
25 
27 {
28  Stop();
29 }
30 
31 
32 
33 
34 
35 void cIsThread::Start(void)
36 {
37  // Initialize the thread:
38  m_Thread = std::thread(&cIsThread::Entrypoint, this);
39 
40  // Notify the thread that initialization is complete and it can run its code safely:
42 }
43 
44 
45 
46 
47 
48 void cIsThread::Stop(void)
49 {
50  m_ShouldTerminate = true;
51  {
52  LOGD("Waiting for the %s thread to finish", m_ThreadName.c_str());
53  if (m_Thread.joinable())
54  {
55  m_Thread.join();
56  }
57  LOGD("The %s thread finished", m_ThreadName.c_str());
58  }
59  m_ShouldTerminate = false;
60 }
61 
62 
63 
64 
65 
67 {
68  // Apply thread naming:
69  SetThreadName();
70 
71  // Wait for initialisation:
73 
74  try
75  {
76  Execute();
77  }
78  catch (const std::exception & Oops)
79  {
80  LOGERROR("Thread %s faulted with standard exception: %s", m_ThreadName.c_str(), Oops.what());
81  std::abort();
82  }
83  catch (...)
84  {
85  LOGERROR("Thread %s faulted with unknown exception!", m_ThreadName.c_str());
86  std::abort();
87  }
88 }
89 
90 
91 
92 
93 
95 {
96 #if defined(_MSC_VER) && !defined(NDEBUG)
97  /* Sets the name of this thread.
98  (When in MSVC, the debugger provides "thread naming" by catching special exceptions)
99  Code adapted from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */
100 
101  if (m_ThreadName.empty())
102  {
103  return;
104  }
105 
106 #pragma pack(push, 8)
107  struct THREADNAME_INFO
108  {
109  DWORD dwType; // Must be 0x1000.
110  LPCSTR szName; // Pointer to name (in user addr space).
111  DWORD dwThreadID; // Thread ID (-1 = caller thread).
112  DWORD dwFlags; // Reserved for future use, must be zero.
113  };
114 #pragma pack(pop)
115 
116  const DWORD NAME_EXCEPTION = 0x406D1388;
117  const THREADNAME_INFO Name = { 0x1000, m_ThreadName.c_str(), static_cast<DWORD>(-1), 0 };
118 
119  __try
120  {
121  RaiseException(NAME_EXCEPTION, 0, sizeof(Name) / sizeof(ULONG_PTR), reinterpret_cast<const ULONG_PTR *>(&Name));
122  }
123  __except (EXCEPTION_EXECUTE_HANDLER)
124  {
125  }
126 #endif
127 }
void LOGERROR(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:73
#define LOGD
Definition: LoggerSimple.h:83
std::string AString
Definition: StringUtils.h:11
Definition: FastNBT.h:132
void Wait(void)
Waits until the event has been set.
Definition: Event.cpp:23
void Set(void)
Sets the event - releases one thread that has been waiting in Wait().
Definition: Event.cpp:52
std::atomic< bool > m_ShouldTerminate
The overriden Execute() method should check this value periodically and terminate if this is true.
Definition: IsThread.h:45
cIsThread(AString &&a_ThreadName)
Definition: IsThread.cpp:16
virtual ~cIsThread()
Definition: IsThread.cpp:26
void Stop(void)
Signals the thread to terminate and waits until it's finished.
Definition: IsThread.cpp:48
void Entrypoint(void)
This is the main thread entrypoint.
Definition: IsThread.cpp:66
AString m_ThreadName
The name of the thread, used to aid debugging in IDEs which support named threads.
Definition: IsThread.h:53
std::thread m_Thread
The thread object which holds the created thread for later manipulation.
Definition: IsThread.h:50
cEvent m_Initialisation
The event that is used to wait with the thread's execution until the thread object is fully initializ...
Definition: IsThread.h:57
void Start(void)
Starts the thread; returns without waiting for the actual start.
Definition: IsThread.cpp:35
virtual void Execute(void)=0
This function, overloaded by the descendants, is called in the new thread.
void SetThreadName() const
Sets the name of the current thread to be the name provided in m_ThreadName.
Definition: IsThread.cpp:94