@@ -28,6 +28,8 @@ | |||||
START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
class Signal; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Mutex class | // Mutex class | ||||
@@ -40,12 +42,12 @@ public: | |||||
Mutex(bool inheritPriority = true) noexcept | Mutex(bool inheritPriority = true) noexcept | ||||
: fMutex() | : 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 | #ifdef DISTRHO_OS_WINDOWS | ||||
InitializeCriticalSection(&fSection); | InitializeCriticalSection(&fSection); | ||||
#else | #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 | #endif | ||||
} | } | ||||
@@ -176,6 +178,87 @@ private: | |||||
DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex) | 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. | // Helper class to lock&unlock a mutex during a function scope. | ||||
@@ -19,6 +19,8 @@ | |||||
#include "../DistrhoUtils.hpp" | #include "../DistrhoUtils.hpp" | ||||
#include <algorithm> | |||||
START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -577,7 +579,7 @@ public: | |||||
"abcdefghijklmnopqrstuvwxyz" | "abcdefghijklmnopqrstuvwxyz" | ||||
"0123456789+/"; | "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); | const uchar* bytesToEncode((const uchar*)data); | ||||
@@ -21,7 +21,7 @@ | |||||
#include "Sleep.hpp" | #include "Sleep.hpp" | ||||
#include "String.hpp" | #include "String.hpp" | ||||
#ifdef DISTRHO_OS_LINUX | |||||
#ifdef DISTRHO_OS_LINUX_FULL | |||||
# include <sys/prctl.h> | # include <sys/prctl.h> | ||||
#endif | #endif | ||||
@@ -37,7 +37,8 @@ protected: | |||||
* Constructor. | * Constructor. | ||||
*/ | */ | ||||
Thread(const char* const threadName = nullptr) noexcept | Thread(const char* const threadName = nullptr) noexcept | ||||
: fLock(false), | |||||
: fLock(), | |||||
fSignal(), | |||||
fName(threadName), | fName(threadName), | ||||
#ifdef PTW32_DLLPORT | #ifdef PTW32_DLLPORT | ||||
fHandle({nullptr, 0}), | fHandle({nullptr, 0}), | ||||
@@ -92,7 +93,7 @@ public: | |||||
// check if already running | // check if already running | ||||
DISTRHO_SAFE_ASSERT_RETURN(! isThreadRunning(), true); | DISTRHO_SAFE_ASSERT_RETURN(! isThreadRunning(), true); | ||||
const MutexLocker cml(fLock); | |||||
const MutexLocker ml(fLock); | |||||
fShouldExit = false; | fShouldExit = false; | ||||
@@ -109,8 +110,7 @@ public: | |||||
_copyFrom(handle); | _copyFrom(handle); | ||||
// wait for thread to start | // wait for thread to start | ||||
fLock.lock(); | |||||
fSignal.wait(); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -126,7 +126,7 @@ public: | |||||
*/ | */ | ||||
bool stopThread(const int timeOutMilliseconds) noexcept | bool stopThread(const int timeOutMilliseconds) noexcept | ||||
{ | { | ||||
const MutexLocker cml(fLock); | |||||
const MutexLocker ml(fLock); | |||||
if (isThreadRunning()) | if (isThreadRunning()) | ||||
{ | { | ||||
@@ -198,7 +198,7 @@ public: | |||||
{ | { | ||||
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); | 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); | prctl(PR_SET_NAME, name, 0, 0, 0); | ||||
#endif | #endif | ||||
#if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 | #if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 | ||||
@@ -210,6 +210,7 @@ public: | |||||
private: | private: | ||||
Mutex fLock; // Thread lock | Mutex fLock; // Thread lock | ||||
Signal fSignal; // Thread start wait signal | |||||
const String fName; // Thread name | const String fName; // Thread name | ||||
volatile pthread_t fHandle; // Handle for this thread | volatile pthread_t fHandle; // Handle for this thread | ||||
volatile bool fShouldExit; // true if thread should exit | volatile bool fShouldExit; // true if thread should exit | ||||
@@ -258,11 +259,11 @@ private: | |||||
*/ | */ | ||||
void _runEntryPoint() noexcept | void _runEntryPoint() noexcept | ||||
{ | { | ||||
// report ready | |||||
fLock.unlock(); | |||||
setCurrentThreadName(fName); | setCurrentThreadName(fName); | ||||
// report ready | |||||
fSignal.signal(); | |||||
try { | try { | ||||
run(); | run(); | ||||
} catch(...) {} | } catch(...) {} | ||||
@@ -37,7 +37,10 @@ | |||||
# define DISTRHO_DLL_EXTENSION "dylib" | # define DISTRHO_DLL_EXTENSION "dylib" | ||||
# elif defined(__HAIKU__) | # elif defined(__HAIKU__) | ||||
# define DISTRHO_OS_HAIKU 1 | # 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 | # define DISTRHO_OS_LINUX 1 | ||||
# endif | # endif | ||||
#endif | #endif | ||||
@@ -309,7 +309,7 @@ public: | |||||
fURIDs.timeFrame, &frame, | fURIDs.timeFrame, &frame, | ||||
fURIDs.timeSpeed, &speed, | fURIDs.timeSpeed, &speed, | ||||
fURIDs.timeTicksPerBeat, &ticksPerBeat, | fURIDs.timeTicksPerBeat, &ticksPerBeat, | ||||
nullptr); | |||||
0); | |||||
// need to handle this first as other values depend on it | // need to handle this first as other values depend on it | ||||
if (ticksPerBeat != nullptr) | if (ticksPerBeat != nullptr) | ||||
@@ -9,10 +9,10 @@ build: ../lv2_ttl_generator | |||||
endif | endif | ||||
../lv2_ttl_generator: lv2_ttl_generator.c | ../lv2_ttl_generator: lv2_ttl_generator.c | ||||
$(CC) $< -o $@ -ldl | |||||
$(CC) $< $(CFLAGS) -o $@ $(LDFLAGS) -ldl | |||||
../lv2_ttl_generator.exe: lv2_ttl_generator.c | ../lv2_ttl_generator.exe: lv2_ttl_generator.c | ||||
$(CC) $< -o $@ -static | |||||
$(CC) $< $(CFLAGS) -o $@ $(LDFLAGS) -static | |||||
touch ../lv2_ttl_generator | touch ../lv2_ttl_generator | ||||
clean: | clean: | ||||