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(
const bool withRealtimePriority = 
false) noexcept
 
   94         DISTRHO_SAFE_ASSERT_RETURN(! isThreadRunning(), 
true);
 
   99         pthread_attr_init(&attr);
 
  101         struct sched_param sched_param;
 
  102         std::memset(&sched_param, 0, 
sizeof(sched_param));
 
  104         if (withRealtimePriority)
 
  106             sched_param.sched_priority = 80;
 
  108 #ifndef DISTRHO_OS_HAIKU 
  109             if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)          == 0  &&
 
  110                 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0  &&
 
  111 # ifndef DISTRHO_OS_WINDOWS
 
  112                (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)              == 0  ||
 
  113                 pthread_attr_setschedpolicy(&attr, SCHED_RR)                == 0) &&
 
  115                 pthread_attr_setschedparam(&attr, &sched_param)             == 0)
 
  117                 d_stdout(
"Thread setup with realtime priority successful");
 
  122                 d_stdout(
"Thread setup with realtime priority failed, going with normal priority instead");
 
  123                 pthread_attr_destroy(&attr);
 
  124                 pthread_attr_init(&attr);
 
  132         bool ok = pthread_create(&handle, &attr, _entryPoint, 
this) == 0;
 
  133         pthread_attr_destroy(&attr);
 
  135         if (withRealtimePriority && !ok)
 
  137             d_stdout(
"Thread with realtime priority failed on creation, going with normal priority instead");
 
  138             pthread_attr_init(&attr);
 
  139             ok = pthread_create(&handle, &attr, _entryPoint, 
this) == 0;
 
  140             pthread_attr_destroy(&attr);
 
  143         DISTRHO_SAFE_ASSERT_RETURN(ok, 
false);
 
  145         DISTRHO_SAFE_ASSERT_RETURN(handle.p != 
nullptr, 
false);
 
  147         DISTRHO_SAFE_ASSERT_RETURN(handle != 0, 
false);
 
  149         pthread_detach(handle);
 
  164     bool stopThread(
const int timeOutMilliseconds) noexcept
 
  168         if (isThreadRunning())
 
  170             signalThreadShouldExit();
 
  172             if (timeOutMilliseconds != 0)
 
  175                 int timeOutCheck = (timeOutMilliseconds == 1 || timeOutMilliseconds == -1) ? timeOutMilliseconds : timeOutMilliseconds/2;
 
  177                 for (; isThreadRunning();)
 
  181                     if (timeOutCheck < 0)
 
  184                     if (timeOutCheck > 0)
 
  191             if (isThreadRunning())
 
  194                 d_stderr2(
"assertion failure: \"! isThreadRunning()\" in file %s, line %i", __FILE__, __LINE__);
 
  201                 pthread_detach(threadId);
 
  212     void signalThreadShouldExit() noexcept
 
  223     const String& getThreadName() 
const noexcept
 
  231     pthread_t getThreadId() 
const noexcept
 
  239     static void setCurrentThreadName(
const char* 
const name) noexcept
 
  241         DISTRHO_SAFE_ASSERT_RETURN(name != 
nullptr && name[0] != 
'\0',);
 
  243 #ifdef DISTRHO_OS_LINUX 
  244         prctl(PR_SET_NAME, name, 0, 0, 0);
 
  246 #if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 && !defined(DISTRHO_OS_GNU_HURD) 
  247         pthread_setname_np(pthread_self(), name);
 
  257     volatile pthread_t fHandle;     
 
  258     volatile bool      fShouldExit; 
 
  263     void _init() noexcept
 
  276     void _copyFrom(
const pthread_t& handle) noexcept
 
  279         fHandle.p = handle.p;
 
  280         fHandle.x = handle.x;
 
  289     void _copyTo(
volatile pthread_t& handle) 
const noexcept
 
  292         handle.p = fHandle.p;
 
  293         handle.x = fHandle.x;
 
  302     void _runEntryPoint() noexcept
 
  304         if (fName.isNotEmpty())
 
  305             setCurrentThreadName(fName);
 
  321     static void* _entryPoint(
void* userData) noexcept
 
  323         static_cast<Thread*
>(userData)->_runEntryPoint();
 
  327     DISTRHO_DECLARE_NON_COPYABLE(
Thread)
 
  332 END_NAMESPACE_DISTRHO
 
  334 #endif // DISTRHO_THREAD_HPP_INCLUDED