17 #ifndef DISTRHO_THREAD_HPP_INCLUDED
18 #define DISTRHO_THREAD_HPP_INCLUDED
24 #ifdef DISTRHO_OS_LINUX
25 # include <sys/prctl.h>
28 START_NAMESPACE_DISTRHO
39 Thread(
const char*
const threadName =
nullptr) noexcept
44 fHandle({
nullptr, 0}),
55 DISTRHO_SAFE_ASSERT(! isThreadRunning());
63 virtual void run() = 0;
71 bool isThreadRunning()
const noexcept
74 return (fHandle.p !=
nullptr);
76 return (fHandle != 0);
83 bool shouldThreadExit()
const noexcept
91 bool startThread() noexcept
94 DISTRHO_SAFE_ASSERT_RETURN(! isThreadRunning(),
true);
102 if (pthread_create(&handle,
nullptr, _entryPoint,
this) == 0)
105 DISTRHO_SAFE_ASSERT_RETURN(handle.p !=
nullptr,
false);
107 DISTRHO_SAFE_ASSERT_RETURN(handle != 0,
false);
109 pthread_detach(handle);
127 bool stopThread(
const int timeOutMilliseconds) noexcept
131 if (isThreadRunning())
133 signalThreadShouldExit();
135 if (timeOutMilliseconds != 0)
138 int timeOutCheck = (timeOutMilliseconds == 1 || timeOutMilliseconds == -1) ? timeOutMilliseconds : timeOutMilliseconds/2;
140 for (; isThreadRunning();)
144 if (timeOutCheck < 0)
147 if (timeOutCheck > 0)
154 if (isThreadRunning())
157 d_stderr2(
"assertion failure: \"! isThreadRunning()\" in file %s, line %i", __FILE__, __LINE__);
165 pthread_cancel(threadId);
166 } DISTRHO_SAFE_EXCEPTION(
"pthread_cancel");
178 void signalThreadShouldExit() noexcept
189 const String& getThreadName()
const noexcept
197 static void setCurrentThreadName(
const char*
const name) noexcept
199 DISTRHO_SAFE_ASSERT_RETURN(name !=
nullptr && name[0] !=
'\0',);
201 #ifdef DISTRHO_OS_LINUX
202 prctl(PR_SET_NAME, name, 0, 0, 0);
204 #if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012
205 pthread_setname_np(pthread_self(), name);
215 volatile pthread_t fHandle;
216 volatile bool fShouldExit;
221 void _init() noexcept
234 void _copyFrom(
const pthread_t& handle) noexcept
237 fHandle.p = handle.p;
238 fHandle.x = handle.x;
247 void _copyTo(
volatile pthread_t& handle)
const noexcept
250 handle.p = fHandle.p;
251 handle.x = fHandle.x;
260 void _runEntryPoint() noexcept
262 setCurrentThreadName(fName);
278 static void* _entryPoint(
void* userData) noexcept
280 static_cast<Thread*
>(userData)->_runEntryPoint();
284 DISTRHO_DECLARE_NON_COPY_CLASS(
Thread)
289 END_NAMESPACE_DISTRHO
291 #endif // DISTRHO_THREAD_HPP_INCLUDED