@@ -21,6 +21,7 @@ | |||||
#ifdef DISTRHO_OS_UNIX | #ifdef DISTRHO_OS_UNIX | ||||
# include <cerrno> | # include <cerrno> | ||||
# include <signal.h> | |||||
# include <sys/wait.h> | # include <sys/wait.h> | ||||
# include <unistd.h> | # include <unistd.h> | ||||
#else | #else | ||||
@@ -28,6 +28,8 @@ | |||||
START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
class Signal; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Mutex class | // Mutex class | ||||
@@ -40,12 +42,14 @@ 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_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); | |||||
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); | |||||
pthread_mutex_init(&fMutex, &attr); | |||||
pthread_mutexattr_destroy(&attr); | |||||
} | } | ||||
/* | /* | ||||
@@ -84,6 +88,7 @@ public: | |||||
private: | private: | ||||
mutable pthread_mutex_t fMutex; | mutable pthread_mutex_t fMutex; | ||||
friend class Signal; | |||||
DISTRHO_PREVENT_HEAP_ALLOCATION | DISTRHO_PREVENT_HEAP_ALLOCATION | ||||
DISTRHO_DECLARE_NON_COPY_CLASS(Mutex) | DISTRHO_DECLARE_NON_COPY_CLASS(Mutex) | ||||
}; | }; | ||||
@@ -107,12 +112,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 +181,68 @@ private: | |||||
DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex) | DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex) | ||||
}; | }; | ||||
// ----------------------------------------------------------------------- | |||||
// Signal class | |||||
class Signal | |||||
{ | |||||
public: | |||||
/* | |||||
* Constructor. | |||||
*/ | |||||
Signal(Mutex& mutex) noexcept | |||||
: fCondition(), | |||||
fMutex(mutex.fMutex) | |||||
{ | |||||
pthread_condattr_t attr; | |||||
pthread_condattr_init(&attr); | |||||
pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); | |||||
pthread_cond_init(&fCondition, &attr); | |||||
pthread_condattr_destroy(&attr); | |||||
} | |||||
/* | |||||
* Destructor. | |||||
*/ | |||||
~Signal() noexcept | |||||
{ | |||||
pthread_cond_destroy(&fCondition); | |||||
} | |||||
/* | |||||
* Wait for a broadcast. | |||||
*/ | |||||
bool wait() noexcept | |||||
{ | |||||
try { | |||||
return (pthread_cond_wait(&fCondition, &fMutex) == 0); | |||||
} DISTRHO_SAFE_EXCEPTION_RETURN("pthread_cond_wait", false); | |||||
} | |||||
/* | |||||
* Wake up one waiting thread. | |||||
*/ | |||||
void signal() noexcept | |||||
{ | |||||
pthread_cond_signal(&fCondition); | |||||
} | |||||
/* | |||||
* Wake up all waiting threads. | |||||
*/ | |||||
void broadcast() noexcept | |||||
{ | |||||
pthread_cond_broadcast(&fCondition); | |||||
} | |||||
private: | |||||
pthread_cond_t fCondition; | |||||
pthread_mutex_t& fMutex; | |||||
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); | ||||
@@ -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(fLock), | |||||
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); | |||||
fLock.lock(); | |||||
fShouldExit = false; | fShouldExit = false; | ||||
@@ -109,11 +110,11 @@ public: | |||||
_copyFrom(handle); | _copyFrom(handle); | ||||
// wait for thread to start | // wait for thread to start | ||||
fLock.lock(); | |||||
fSignal.wait(); | |||||
return true; | return true; | ||||
} | } | ||||
fLock.unlock(); | |||||
return false; | return false; | ||||
} | } | ||||
@@ -210,6 +211,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 +260,11 @@ private: | |||||
*/ | */ | ||||
void _runEntryPoint() noexcept | void _runEntryPoint() noexcept | ||||
{ | { | ||||
// report ready | |||||
fLock.unlock(); | |||||
setCurrentThreadName(fName); | setCurrentThreadName(fName); | ||||
// report ready | |||||
fSignal.broadcast(); | |||||
try { | try { | ||||
run(); | run(); | ||||
} catch(...) {} | } catch(...) {} | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla String | * Carla String | ||||
* Copyright (C) 2013-2015 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2013-2016 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -20,6 +20,7 @@ | |||||
#include "CarlaJuceUtils.hpp" | #include "CarlaJuceUtils.hpp" | ||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include <algorithm> | #include <algorithm> | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Thread | * Carla Thread | ||||
* Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2013-2016 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||