| @@ -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 | ||||