@@ -28,6 +28,8 @@ | |||
START_NAMESPACE_DISTRHO | |||
class Signal; | |||
// ----------------------------------------------------------------------- | |||
// Mutex class | |||
@@ -40,12 +42,12 @@ public: | |||
Mutex(bool inheritPriority = true) noexcept | |||
: fMutex() | |||
{ | |||
pthread_mutexattr_t atts; | |||
pthread_mutexattr_init(&atts); | |||
pthread_mutexattr_setprotocol(&atts, inheritPriority ? PTHREAD_PRIO_INHERIT : PTHREAD_PRIO_NONE); | |||
pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_NORMAL); | |||
pthread_mutex_init(&fMutex, &atts); | |||
pthread_mutexattr_destroy(&atts); | |||
pthread_mutexattr_t attr; | |||
pthread_mutexattr_init(&attr); | |||
pthread_mutexattr_setprotocol(&attr, inheritPriority ? PTHREAD_PRIO_INHERIT : PTHREAD_PRIO_NONE); | |||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); | |||
pthread_mutex_init(&fMutex, &attr); | |||
pthread_mutexattr_destroy(&attr); | |||
} | |||
/* | |||
@@ -107,12 +109,12 @@ public: | |||
#ifdef DISTRHO_OS_WINDOWS | |||
InitializeCriticalSection(&fSection); | |||
#else | |||
pthread_mutexattr_t atts; | |||
pthread_mutexattr_init(&atts); | |||
pthread_mutexattr_setprotocol(&atts, PTHREAD_PRIO_INHERIT); | |||
pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE); | |||
pthread_mutex_init(&fMutex, &atts); | |||
pthread_mutexattr_destroy(&atts); | |||
pthread_mutexattr_t attr; | |||
pthread_mutexattr_init(&attr); | |||
pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); | |||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | |||
pthread_mutex_init(&fMutex, &attr); | |||
pthread_mutexattr_destroy(&attr); | |||
#endif | |||
} | |||
@@ -176,6 +178,87 @@ private: | |||
DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex) | |||
}; | |||
// ----------------------------------------------------------------------- | |||
// Signal class | |||
class Signal | |||
{ | |||
public: | |||
/* | |||
* Constructor. | |||
*/ | |||
Signal() noexcept | |||
: fCondition(), | |||
fMutex(), | |||
fTriggered(false) | |||
{ | |||
pthread_condattr_t cattr; | |||
pthread_condattr_init(&cattr); | |||
pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_PRIVATE); | |||
pthread_cond_init(&fCondition, &cattr); | |||
pthread_condattr_destroy(&cattr); | |||
pthread_mutexattr_t mattr; | |||
pthread_mutexattr_init(&mattr); | |||
pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT); | |||
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_NORMAL); | |||
pthread_mutex_init(&fMutex, &mattr); | |||
pthread_mutexattr_destroy(&mattr); | |||
} | |||
/* | |||
* Destructor. | |||
*/ | |||
~Signal() noexcept | |||
{ | |||
pthread_cond_destroy(&fCondition); | |||
pthread_mutex_destroy(&fMutex); | |||
} | |||
/* | |||
* Wait for a signal. | |||
*/ | |||
void wait() noexcept | |||
{ | |||
pthread_mutex_lock(&fMutex); | |||
while (! fTriggered) | |||
{ | |||
try { | |||
pthread_cond_wait(&fCondition, &fMutex); | |||
} DISTRHO_SAFE_EXCEPTION("pthread_cond_wait"); | |||
} | |||
fTriggered = false; | |||
pthread_mutex_unlock(&fMutex); | |||
} | |||
/* | |||
* Wake up all waiting threads. | |||
*/ | |||
void signal() noexcept | |||
{ | |||
pthread_mutex_lock(&fMutex); | |||
if (! fTriggered) | |||
{ | |||
fTriggered = true; | |||
pthread_cond_broadcast(&fCondition); | |||
} | |||
pthread_mutex_unlock(&fMutex); | |||
} | |||
private: | |||
pthread_cond_t fCondition; | |||
pthread_mutex_t fMutex; | |||
volatile bool fTriggered; | |||
DISTRHO_PREVENT_HEAP_ALLOCATION | |||
DISTRHO_DECLARE_NON_COPY_CLASS(Signal) | |||
}; | |||
// ----------------------------------------------------------------------- | |||
// Helper class to lock&unlock a mutex during a function scope. | |||
@@ -19,6 +19,8 @@ | |||
#include "../DistrhoUtils.hpp" | |||
#include <algorithm> | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
@@ -577,7 +579,7 @@ public: | |||
"abcdefghijklmnopqrstuvwxyz" | |||
"0123456789+/"; | |||
const std::size_t kTmpBufSize = d_nextPowerOf2(dataSize/3); | |||
const std::size_t kTmpBufSize = std::min(d_nextPowerOf2(dataSize/3), 65536U); | |||
const uchar* bytesToEncode((const uchar*)data); | |||
@@ -21,7 +21,7 @@ | |||
#include "Sleep.hpp" | |||
#include "String.hpp" | |||
#ifdef DISTRHO_OS_LINUX | |||
#ifdef DISTRHO_OS_LINUX_FULL | |||
# include <sys/prctl.h> | |||
#endif | |||
@@ -37,7 +37,8 @@ protected: | |||
* Constructor. | |||
*/ | |||
Thread(const char* const threadName = nullptr) noexcept | |||
: fLock(false), | |||
: fLock(), | |||
fSignal(), | |||
fName(threadName), | |||
#ifdef PTW32_DLLPORT | |||
fHandle({nullptr, 0}), | |||
@@ -92,7 +93,7 @@ public: | |||
// check if already running | |||
DISTRHO_SAFE_ASSERT_RETURN(! isThreadRunning(), true); | |||
const MutexLocker cml(fLock); | |||
const MutexLocker ml(fLock); | |||
fShouldExit = false; | |||
@@ -109,8 +110,7 @@ public: | |||
_copyFrom(handle); | |||
// wait for thread to start | |||
fLock.lock(); | |||
fSignal.wait(); | |||
return true; | |||
} | |||
@@ -126,7 +126,7 @@ public: | |||
*/ | |||
bool stopThread(const int timeOutMilliseconds) noexcept | |||
{ | |||
const MutexLocker cml(fLock); | |||
const MutexLocker ml(fLock); | |||
if (isThreadRunning()) | |||
{ | |||
@@ -198,7 +198,7 @@ public: | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); | |||
#ifdef DISTRHO_OS_LINUX | |||
#ifdef DISTRHO_OS_LINUX_FULL | |||
prctl(PR_SET_NAME, name, 0, 0, 0); | |||
#endif | |||
#if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 | |||
@@ -210,6 +210,7 @@ public: | |||
private: | |||
Mutex fLock; // Thread lock | |||
Signal fSignal; // Thread start wait signal | |||
const String fName; // Thread name | |||
volatile pthread_t fHandle; // Handle for this thread | |||
volatile bool fShouldExit; // true if thread should exit | |||
@@ -258,11 +259,11 @@ private: | |||
*/ | |||
void _runEntryPoint() noexcept | |||
{ | |||
// report ready | |||
fLock.unlock(); | |||
setCurrentThreadName(fName); | |||
// report ready | |||
fSignal.signal(); | |||
try { | |||
run(); | |||
} catch(...) {} | |||
@@ -37,7 +37,10 @@ | |||
# define DISTRHO_DLL_EXTENSION "dylib" | |||
# elif defined(__HAIKU__) | |||
# define DISTRHO_OS_HAIKU 1 | |||
# elif defined(__linux__) | |||
# elif defined(__linux__) || defined(__linux) | |||
# define DISTRHO_OS_LINUX 1 | |||
# define DISTRHO_OS_LINUX_FULL 1 | |||
# elif defined(__FreeBSD__) || defined(__GNU__) | |||
# define DISTRHO_OS_LINUX 1 | |||
# endif | |||
#endif | |||
@@ -309,7 +309,7 @@ public: | |||
fURIDs.timeFrame, &frame, | |||
fURIDs.timeSpeed, &speed, | |||
fURIDs.timeTicksPerBeat, &ticksPerBeat, | |||
nullptr); | |||
0); | |||
// need to handle this first as other values depend on it | |||
if (ticksPerBeat != nullptr) | |||
@@ -9,10 +9,10 @@ build: ../lv2_ttl_generator | |||
endif | |||
../lv2_ttl_generator: lv2_ttl_generator.c | |||
$(CC) $< -o $@ -ldl | |||
$(CC) $< $(CFLAGS) -o $@ $(LDFLAGS) -ldl | |||
../lv2_ttl_generator.exe: lv2_ttl_generator.c | |||
$(CC) $< -o $@ -static | |||
$(CC) $< $(CFLAGS) -o $@ $(LDFLAGS) -static | |||
touch ../lv2_ttl_generator | |||
clean: | |||