| @@ -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> | |||
| // ----------------------------------------------------------------------- | |||
| // d_mutex class | |||
| class d_mutex | |||
| { | |||
| public: | |||
| /* | |||
| * Constructor. | |||
| */ | |||
| d_mutex() noexcept | |||
| { | |||
| pthread_mutex_init(&fMutex, nullptr); | |||
| } | |||
| /* | |||
| * Destructor. | |||
| */ | |||
| ~d_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, optionally resetting the tryLock check. | |||
| */ | |||
| void unlock() const noexcept | |||
| { | |||
| pthread_mutex_unlock(&fMutex); | |||
| } | |||
| private: | |||
| mutable pthread_mutex_t fMutex; | |||
| DISTRHO_PREVENT_HEAP_ALLOCATION | |||
| DISTRHO_DECLARE_NON_COPY_CLASS(d_mutex) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // d_rmutex class | |||
| class d_rmutex | |||
| { | |||
| public: | |||
| /* | |||
| * Constructor. | |||
| */ | |||
| d_rmutex() noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| 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. | |||
| */ | |||
| ~d_rmutex() noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| DeleteCriticalSection(&fSection); | |||
| #else | |||
| pthread_mutex_destroy(&fMutex); | |||
| #endif | |||
| } | |||
| /* | |||
| * Lock the mutex. | |||
| */ | |||
| void lock() const noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| EnterCriticalSection(&fSection); | |||
| #else | |||
| pthread_mutex_lock(&fMutex); | |||
| #endif | |||
| } | |||
| /* | |||
| * Try to lock the mutex. | |||
| * Returns true if successful. | |||
| */ | |||
| bool tryLock() const noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| return (TryEnterCriticalSection(&fSection) != FALSE); | |||
| #else | |||
| return (pthread_mutex_trylock(&fMutex) == 0); | |||
| #endif | |||
| } | |||
| /* | |||
| * Unlock the mutex. | |||
| */ | |||
| void unlock() const noexcept | |||
| { | |||
| #ifdef DISTRHO_OS_WIN | |||
| LeaveCriticalSection(&fSection); | |||
| #else | |||
| pthread_mutex_unlock(&fMutex); | |||
| #endif | |||
| } | |||
| private: | |||
| #ifdef DISTRHO_OS_WIN | |||
| mutable CRITICAL_SECTION fSection; | |||
| #else | |||
| mutable pthread_mutex_t fMutex; | |||
| #endif | |||
| DISTRHO_PREVENT_HEAP_ALLOCATION | |||
| DISTRHO_DECLARE_NON_COPY_CLASS(d_rmutex) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to lock&unlock a mutex during a function scope. | |||
| template <class Mutex> | |||
| class d_scopeLocker | |||
| { | |||
| public: | |||
| d_scopeLocker(const Mutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| ~d_scopeLocker() noexcept | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| private: | |||
| const Mutex& fMutex; | |||
| DISTRHO_PREVENT_HEAP_ALLOCATION | |||
| DISTRHO_DECLARE_NON_COPY_CLASS(d_scopeLocker) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Helper class to unlock&lock a mutex during a function scope. | |||
| template <class Mutex> | |||
| class d_scopeUnlocker | |||
| { | |||
| public: | |||
| d_scopeUnlocker(const Mutex& mutex) noexcept | |||
| : fMutex(mutex) | |||
| { | |||
| fMutex.unlock(); | |||
| } | |||
| ~d_scopeUnlocker() noexcept | |||
| { | |||
| fMutex.lock(); | |||
| } | |||
| private: | |||
| const Mutex& fMutex; | |||
| DISTRHO_PREVENT_HEAP_ALLOCATION | |||
| DISTRHO_DECLARE_NON_COPY_CLASS(d_scopeUnlocker) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // Define types | |||
| typedef d_scopeLocker<d_mutex> d_mutexLocker; | |||
| typedef d_scopeLocker<d_rmutex> d_rmutexLocker; | |||
| typedef d_scopeUnlocker<d_mutex> d_mutexUnlocker; | |||
| typedef d_scopeUnlocker<d_rmutex> d_rmutexUnlocker; | |||
| // ----------------------------------------------------------------------- | |||
| #endif // DISTRHO_MUTEX_HPP_INCLUDED | |||