Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
4.9KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifndef DISTRHO_MUTEX_HPP_INCLUDED
  17. #define DISTRHO_MUTEX_HPP_INCLUDED
  18. #include "../DistrhoUtils.hpp"
  19. #ifdef DISTRHO_OS_WINDOWS
  20. # include <winsock2.h>
  21. # include <windows.h>
  22. #endif
  23. #include <pthread.h>
  24. START_NAMESPACE_DISTRHO
  25. // -----------------------------------------------------------------------
  26. // Mutex class
  27. class Mutex
  28. {
  29. public:
  30. /*
  31. * Constructor.
  32. */
  33. Mutex() noexcept
  34. {
  35. pthread_mutex_init(&fMutex, nullptr);
  36. }
  37. /*
  38. * Destructor.
  39. */
  40. ~Mutex() noexcept
  41. {
  42. pthread_mutex_destroy(&fMutex);
  43. }
  44. /*
  45. * Lock the mutex.
  46. */
  47. void lock() const noexcept
  48. {
  49. pthread_mutex_lock(&fMutex);
  50. }
  51. /*
  52. * Try to lock the mutex.
  53. * Returns true if successful.
  54. */
  55. bool tryLock() const noexcept
  56. {
  57. return (pthread_mutex_trylock(&fMutex) == 0);
  58. }
  59. /*
  60. * Unlock the mutex.
  61. */
  62. void unlock() const noexcept
  63. {
  64. pthread_mutex_unlock(&fMutex);
  65. }
  66. private:
  67. mutable pthread_mutex_t fMutex;
  68. DISTRHO_PREVENT_HEAP_ALLOCATION
  69. DISTRHO_DECLARE_NON_COPY_CLASS(Mutex)
  70. };
  71. // -----------------------------------------------------------------------
  72. // RecursiveMutex class
  73. class RecursiveMutex
  74. {
  75. public:
  76. /*
  77. * Constructor.
  78. */
  79. RecursiveMutex() noexcept
  80. {
  81. #ifdef DISTRHO_OS_WINDOWS
  82. InitializeCriticalSection(&fSection);
  83. #else
  84. pthread_mutexattr_t atts;
  85. pthread_mutexattr_init(&atts);
  86. pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE);
  87. pthread_mutex_init(&fMutex, &atts);
  88. pthread_mutexattr_destroy(&atts);
  89. #endif
  90. }
  91. /*
  92. * Destructor.
  93. */
  94. ~RecursiveMutex() noexcept
  95. {
  96. #ifdef DISTRHO_OS_WINDOWS
  97. DeleteCriticalSection(&fSection);
  98. #else
  99. pthread_mutex_destroy(&fMutex);
  100. #endif
  101. }
  102. /*
  103. * Lock the mutex.
  104. */
  105. void lock() const noexcept
  106. {
  107. #ifdef DISTRHO_OS_WINDOWS
  108. EnterCriticalSection(&fSection);
  109. #else
  110. pthread_mutex_lock(&fMutex);
  111. #endif
  112. }
  113. /*
  114. * Try to lock the mutex.
  115. * Returns true if successful.
  116. */
  117. bool tryLock() const noexcept
  118. {
  119. #ifdef DISTRHO_OS_WINDOWS
  120. return (TryEnterCriticalSection(&fSection) != FALSE);
  121. #else
  122. return (pthread_mutex_trylock(&fMutex) == 0);
  123. #endif
  124. }
  125. /*
  126. * Unlock the mutex.
  127. */
  128. void unlock() const noexcept
  129. {
  130. #ifdef DISTRHO_OS_WINDOWS
  131. LeaveCriticalSection(&fSection);
  132. #else
  133. pthread_mutex_unlock(&fMutex);
  134. #endif
  135. }
  136. private:
  137. #ifdef DISTRHO_OS_WINDOWS
  138. mutable CRITICAL_SECTION fSection;
  139. #else
  140. mutable pthread_mutex_t fMutex;
  141. #endif
  142. DISTRHO_PREVENT_HEAP_ALLOCATION
  143. DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex)
  144. };
  145. // -----------------------------------------------------------------------
  146. // Helper class to lock&unlock a mutex during a function scope.
  147. template <class Mutex>
  148. class ScopedLocker
  149. {
  150. public:
  151. ScopedLocker(const Mutex& mutex) noexcept
  152. : fMutex(mutex)
  153. {
  154. fMutex.lock();
  155. }
  156. ~ScopedLocker() noexcept
  157. {
  158. fMutex.unlock();
  159. }
  160. private:
  161. const Mutex& fMutex;
  162. DISTRHO_PREVENT_HEAP_ALLOCATION
  163. DISTRHO_DECLARE_NON_COPY_CLASS(ScopedLocker)
  164. };
  165. // -----------------------------------------------------------------------
  166. // Helper class to unlock&lock a mutex during a function scope.
  167. template <class Mutex>
  168. class ScopedUnlocker
  169. {
  170. public:
  171. ScopedUnlocker(const Mutex& mutex) noexcept
  172. : fMutex(mutex)
  173. {
  174. fMutex.unlock();
  175. }
  176. ~ScopedUnlocker() noexcept
  177. {
  178. fMutex.lock();
  179. }
  180. private:
  181. const Mutex& fMutex;
  182. DISTRHO_PREVENT_HEAP_ALLOCATION
  183. DISTRHO_DECLARE_NON_COPY_CLASS(ScopedUnlocker)
  184. };
  185. // -----------------------------------------------------------------------
  186. // Define types
  187. typedef ScopedLocker<Mutex> MutexLocker;
  188. typedef ScopedLocker<RecursiveMutex> RecursiveMutexLocker;
  189. typedef ScopedUnlocker<Mutex> MutexUnlocker;
  190. typedef ScopedUnlocker<RecursiveMutex> RecursiveMutexUnlocker;
  191. // -----------------------------------------------------------------------
  192. END_NAMESPACE_DISTRHO
  193. #endif // DISTRHO_MUTEX_HPP_INCLUDED