From 97fb4236d0ece085c7b2ec89d3324acace379d75 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 4 Apr 2016 10:52:22 +0200 Subject: [PATCH] Proper signal class implementation --- distrho/extra/Mutex.hpp | 66 +++++++++++++++++++++++++--------------- distrho/extra/Thread.hpp | 6 ++-- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/distrho/extra/Mutex.hpp b/distrho/extra/Mutex.hpp index 3200e66f..2f80515a 100644 --- a/distrho/extra/Mutex.hpp +++ b/distrho/extra/Mutex.hpp @@ -86,7 +86,6 @@ public: private: mutable pthread_mutex_t fMutex; - friend class Signal; DISTRHO_PREVENT_HEAP_ALLOCATION DISTRHO_DECLARE_NON_COPY_CLASS(Mutex) }; @@ -188,15 +187,23 @@ public: /* * Constructor. */ - Signal(Mutex& mutex) noexcept + Signal() noexcept : fCondition(), - fMutex(mutex.fMutex) + fMutex(), + fTriggered(false) { - pthread_condattr_t attr; - pthread_condattr_init(&attr); - pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); - pthread_cond_init(&fCondition, &attr); - pthread_condattr_destroy(&attr); + 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); } /* @@ -205,37 +212,48 @@ public: ~Signal() noexcept { pthread_cond_destroy(&fCondition); + pthread_mutex_destroy(&fMutex); } /* - * Wait for a broadcast. + * Wait for a signal. */ - bool wait() noexcept + void wait() noexcept { - try { - return (pthread_cond_wait(&fCondition, &fMutex) == 0); - } DISTRHO_SAFE_EXCEPTION_RETURN("pthread_cond_wait", false); - } + pthread_mutex_lock(&fMutex); - /* - * Wake up one waiting thread. - */ - void signal() noexcept - { - pthread_cond_signal(&fCondition); + 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 broadcast() noexcept + void signal() noexcept { - pthread_cond_broadcast(&fCondition); + 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; + pthread_cond_t fCondition; + pthread_mutex_t fMutex; + volatile bool fTriggered; DISTRHO_PREVENT_HEAP_ALLOCATION DISTRHO_DECLARE_NON_COPY_CLASS(Signal) diff --git a/distrho/extra/Thread.hpp b/distrho/extra/Thread.hpp index 37f44970..5738fc60 100644 --- a/distrho/extra/Thread.hpp +++ b/distrho/extra/Thread.hpp @@ -38,7 +38,7 @@ protected: */ Thread(const char* const threadName = nullptr) noexcept : fLock(), - fSignal(fLock), + fSignal(), fName(threadName), #ifdef PTW32_DLLPORT fHandle({nullptr, 0}), @@ -126,7 +126,7 @@ public: */ bool stopThread(const int timeOutMilliseconds) noexcept { - const MutexLocker cml(fLock); + const MutexLocker ml(fLock); if (isThreadRunning()) { @@ -262,7 +262,7 @@ private: setCurrentThreadName(fName); // report ready - fSignal.broadcast(); + fSignal.signal(); try { run();