|
@@ -0,0 +1,221 @@ |
|
|
|
|
|
/* |
|
|
|
|
|
* DISTRHO Plugin Framework (DPF) |
|
|
|
|
|
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> |
|
|
|
|
|
* |
|
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any purpose with |
|
|
|
|
|
* or without fee is hereby granted, provided that the above copyright notice and this |
|
|
|
|
|
* permission notice appear in all copies. |
|
|
|
|
|
* |
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD |
|
|
|
|
|
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN |
|
|
|
|
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
|
|
|
|
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER |
|
|
|
|
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
|
|
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
#ifndef DISTRHO_MUTEX_HPP_INCLUDED |
|
|
|
|
|
#define DISTRHO_MUTEX_HPP_INCLUDED |
|
|
|
|
|
|
|
|
|
|
|
#include "../DistrhoUtils.hpp" |
|
|
|
|
|
|
|
|
|
|
|
#include <pthread.h> |
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
// Mutex class |
|
|
|
|
|
|
|
|
|
|
|
class Mutex |
|
|
|
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
/* |
|
|
|
|
|
* Constructor. |
|
|
|
|
|
*/ |
|
|
|
|
|
Mutex() noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
pthread_mutex_init(&fMutex, nullptr); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Destructor. |
|
|
|
|
|
*/ |
|
|
|
|
|
~Mutex() noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
pthread_mutex_destroy(&fMutex); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Lock the mutex. |
|
|
|
|
|
*/ |
|
|
|
|
|
void lock() const noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
pthread_mutex_lock(&fMutex); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Try to lock the mutex. |
|
|
|
|
|
* Returns true if successful. |
|
|
|
|
|
*/ |
|
|
|
|
|
bool tryLock() const noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
return (pthread_mutex_trylock(&fMutex) == 0); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Unlock the mutex. |
|
|
|
|
|
*/ |
|
|
|
|
|
void unlock() const noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
pthread_mutex_unlock(&fMutex); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
mutable pthread_mutex_t fMutex; |
|
|
|
|
|
|
|
|
|
|
|
DISTRHO_PREVENT_HEAP_ALLOCATION |
|
|
|
|
|
DISTRHO_DECLARE_NON_COPY_CLASS(Mutex) |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
// RecursiveMutex class |
|
|
|
|
|
|
|
|
|
|
|
class RecursiveMutex |
|
|
|
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
/* |
|
|
|
|
|
* Constructor. |
|
|
|
|
|
*/ |
|
|
|
|
|
RecursiveMutex() noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
#ifdef DISTRHO_OS_WINDOWS |
|
|
|
|
|
InitializeCriticalSection(&fSection); |
|
|
|
|
|
#else |
|
|
|
|
|
pthread_mutexattr_t atts; |
|
|
|
|
|
pthread_mutexattr_init(&atts); |
|
|
|
|
|
pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE); |
|
|
|
|
|
pthread_mutex_init(&fMutex, &atts); |
|
|
|
|
|
pthread_mutexattr_destroy(&atts); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Destructor. |
|
|
|
|
|
*/ |
|
|
|
|
|
~RecursiveMutex() noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
#ifdef DISTRHO_OS_WINDOWS |
|
|
|
|
|
DeleteCriticalSection(&fSection); |
|
|
|
|
|
#else |
|
|
|
|
|
pthread_mutex_destroy(&fMutex); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Lock the mutex. |
|
|
|
|
|
*/ |
|
|
|
|
|
void lock() const noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
#ifdef DISTRHO_OS_WINDOWS |
|
|
|
|
|
EnterCriticalSection(&fSection); |
|
|
|
|
|
#else |
|
|
|
|
|
pthread_mutex_lock(&fMutex); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Try to lock the mutex. |
|
|
|
|
|
* Returns true if successful. |
|
|
|
|
|
*/ |
|
|
|
|
|
bool tryLock() const noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
#ifdef DISTRHO_OS_WINDOWS |
|
|
|
|
|
return (TryEnterCriticalSection(&fSection) != FALSE); |
|
|
|
|
|
#else |
|
|
|
|
|
return (pthread_mutex_trylock(&fMutex) == 0); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Unlock the mutex. |
|
|
|
|
|
*/ |
|
|
|
|
|
void unlock() const noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
#ifdef DISTRHO_OS_WINDOWS |
|
|
|
|
|
LeaveCriticalSection(&fSection); |
|
|
|
|
|
#else |
|
|
|
|
|
pthread_mutex_unlock(&fMutex); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
#ifdef DISTRHO_OS_WINDOWS |
|
|
|
|
|
mutable CRITICAL_SECTION fSection; |
|
|
|
|
|
#else |
|
|
|
|
|
mutable pthread_mutex_t fMutex; |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
DISTRHO_PREVENT_HEAP_ALLOCATION |
|
|
|
|
|
DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex) |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
// Helper class to lock&unlock a mutex during a function scope. |
|
|
|
|
|
|
|
|
|
|
|
template <class Mutex> |
|
|
|
|
|
class ScopedLocker |
|
|
|
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
ScopedLocker(const Mutex& mutex) noexcept |
|
|
|
|
|
: fMutex(mutex) |
|
|
|
|
|
{ |
|
|
|
|
|
fMutex.lock(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
~ScopedLocker() noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
fMutex.unlock(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
const Mutex& fMutex; |
|
|
|
|
|
|
|
|
|
|
|
DISTRHO_PREVENT_HEAP_ALLOCATION |
|
|
|
|
|
DISTRHO_DECLARE_NON_COPY_CLASS(ScopedLocker) |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
// Helper class to unlock&lock a mutex during a function scope. |
|
|
|
|
|
|
|
|
|
|
|
template <class Mutex> |
|
|
|
|
|
class ScopedUnlocker |
|
|
|
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
ScopedUnlocker(const Mutex& mutex) noexcept |
|
|
|
|
|
: fMutex(mutex) |
|
|
|
|
|
{ |
|
|
|
|
|
fMutex.unlock(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
~ScopedUnlocker() noexcept |
|
|
|
|
|
{ |
|
|
|
|
|
fMutex.lock(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
const Mutex& fMutex; |
|
|
|
|
|
|
|
|
|
|
|
DISTRHO_PREVENT_HEAP_ALLOCATION |
|
|
|
|
|
DISTRHO_DECLARE_NON_COPY_CLASS(ScopedUnlocker) |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
// Define types |
|
|
|
|
|
|
|
|
|
|
|
typedef ScopedLocker<Mutex> MutexLocker; |
|
|
|
|
|
typedef ScopedLocker<RecursiveMutex> RecursiveMutexLocker; |
|
|
|
|
|
|
|
|
|
|
|
typedef ScopedUnlocker<Mutex> MutexUnlocker; |
|
|
|
|
|
typedef ScopedUnlocker<RecursiveMutex> RecursiveMutexUnlocker; |
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
|
|
#endif // DISTRHO_MUTEX_HPP_INCLUDED |