17 #ifndef DISTRHO_THREAD_HPP_INCLUDED 
   18 #define DISTRHO_THREAD_HPP_INCLUDED 
   24 #ifdef DISTRHO_OS_LINUX 
   25 # include <sys/prctl.h> 
   28 #ifdef DISTRHO_OS_WASM 
   29 # error Threads do not work under wasm! 
   43     Thread(
const char* 
const threadName = 
nullptr) noexcept
 
   48           fHandle({
nullptr, 0}),
 
   59         DISTRHO_SAFE_ASSERT(! isThreadRunning());
 
   67     virtual void run() = 0;
 
   75     bool isThreadRunning() 
const noexcept
 
   78         return (fHandle.p != 
nullptr);
 
   80         return (fHandle != 0);
 
   87     bool shouldThreadExit() 
const noexcept
 
   95     bool startThread(
const bool withRealtimePriority = 
false) noexcept
 
   98         DISTRHO_SAFE_ASSERT_RETURN(! isThreadRunning(), 
true);
 
  103         pthread_attr_init(&attr);
 
  105         struct sched_param sched_param = {};
 
  107         if (withRealtimePriority)
 
  109            #ifdef __MOD_DEVICES__ 
  111             const char* 
const srtprio = std::getenv(
"MOD_PLUGIN_THREAD_PRIORITY");
 
  112             if (srtprio != 
nullptr && (rtprio = std::atoi(srtprio)) > 0)
 
  113                 sched_param.sched_priority = rtprio - 1;
 
  116             sched_param.sched_priority = 80;
 
  118            #ifndef DISTRHO_OS_HAIKU 
  119             if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)          == 0  &&
 
  120                 pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0  &&
 
  121               #ifndef DISTRHO_OS_WINDOWS
 
  122                (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)              == 0  ||
 
  123                 pthread_attr_setschedpolicy(&attr, SCHED_RR)                == 0) &&
 
  125                 pthread_attr_setschedparam(&attr, &sched_param)             == 0)
 
  127                 d_stdout(
"Thread setup with realtime priority successful");
 
  132                 d_stdout(
"Thread setup with realtime priority failed, going with normal priority instead");
 
  133                 pthread_attr_destroy(&attr);
 
  134                 pthread_attr_init(&attr);
 
  142         bool ok = pthread_create(&handle, &attr, _entryPoint, 
this) == 0;
 
  143         pthread_attr_destroy(&attr);
 
  145         if (withRealtimePriority && !ok)
 
  147             d_stdout(
"Thread with realtime priority failed on creation, going with normal priority instead");
 
  148             pthread_attr_init(&attr);
 
  149             ok = pthread_create(&handle, &attr, _entryPoint, 
this) == 0;
 
  150             pthread_attr_destroy(&attr);
 
  153         DISTRHO_SAFE_ASSERT_RETURN(ok, 
false);
 
  155         DISTRHO_SAFE_ASSERT_RETURN(handle.p != 
nullptr, 
false);
 
  157         DISTRHO_SAFE_ASSERT_RETURN(handle != 0, 
false);
 
  159         pthread_detach(handle);
 
  174     bool stopThread(
const int timeOutMilliseconds) noexcept
 
  178         if (isThreadRunning())
 
  180             signalThreadShouldExit();
 
  182             if (timeOutMilliseconds != 0)
 
  185                 int timeOutCheck = (timeOutMilliseconds == 1 || timeOutMilliseconds == -1) ? timeOutMilliseconds : timeOutMilliseconds/2;
 
  187                 for (; isThreadRunning();)
 
  191                     if (timeOutCheck < 0)
 
  194                     if (timeOutCheck > 0)
 
  201             if (isThreadRunning())
 
  204                 d_stderr2(
"assertion failure: \"! isThreadRunning()\" in file %s, line %i", __FILE__, __LINE__);
 
  211                 pthread_detach(threadId);
 
  222     void signalThreadShouldExit() noexcept
 
  233     const String& getThreadName() 
const noexcept
 
  241     pthread_t getThreadId() 
const noexcept
 
  249     static void setCurrentThreadName(
const char* 
const name) noexcept
 
  251         DISTRHO_SAFE_ASSERT_RETURN(name != 
nullptr && name[0] != 
'\0',);
 
  253        #ifdef DISTRHO_OS_LINUX 
  254         prctl(PR_SET_NAME, name, 0, 0, 0);
 
  256        #if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 && !defined(DISTRHO_OS_GNU_HURD) 
  257         pthread_setname_np(pthread_self(), name);
 
  267     volatile pthread_t fHandle;     
 
  268     volatile bool      fShouldExit; 
 
  273     void _init() noexcept
 
  286     void _copyFrom(
const pthread_t& handle) noexcept
 
  289         fHandle.p = handle.p;
 
  290         fHandle.x = handle.x;
 
  299     void _copyTo(
volatile pthread_t& handle) 
const noexcept
 
  302         handle.p = fHandle.p;
 
  303         handle.x = fHandle.x;
 
  312     void _runEntryPoint() noexcept
 
  314         if (fName.isNotEmpty())
 
  315             setCurrentThreadName(fName);
 
  331     static void* _entryPoint(
void* userData) noexcept
 
  333         static_cast<Thread*
>(userData)->_runEntryPoint();
 
  337     DISTRHO_DECLARE_NON_COPYABLE(
Thread)
 
Definition: Mutex.hpp:298
 
Definition: Mutex.hpp:215
 
Definition: String.hpp:35
 
Definition: Thread.hpp:38
 
#define END_NAMESPACE_DISTRHO
Definition: DistrhoInfo.hpp:949
 
#define START_NAMESPACE_DISTRHO
Definition: DistrhoInfo.hpp:943
 
static void d_stdout(const char *const fmt,...) noexcept
Definition: DistrhoUtils.hpp:141
 
static void d_stderr2(const char *const fmt,...) noexcept
Definition: DistrhoUtils.hpp:171