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.

275 lines
5.8KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2015 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. : fMutex()
  35. {
  36. pthread_mutex_init(&fMutex, nullptr);
  37. }
  38. /*
  39. * Destructor.
  40. */
  41. ~Mutex() noexcept
  42. {
  43. pthread_mutex_destroy(&fMutex);
  44. }
  45. /*
  46. * Lock the mutex.
  47. */
  48. void lock() const noexcept
  49. {
  50. pthread_mutex_lock(&fMutex);
  51. }
  52. /*
  53. * Try to lock the mutex.
  54. * Returns true if successful.
  55. */
  56. bool tryLock() const noexcept
  57. {
  58. return (pthread_mutex_trylock(&fMutex) == 0);
  59. }
  60. /*
  61. * Unlock the mutex.
  62. */
  63. void unlock() const noexcept
  64. {
  65. pthread_mutex_unlock(&fMutex);
  66. }
  67. private:
  68. mutable pthread_mutex_t fMutex;
  69. DISTRHO_PREVENT_HEAP_ALLOCATION
  70. DISTRHO_DECLARE_NON_COPY_CLASS(Mutex)
  71. };
  72. // -----------------------------------------------------------------------
  73. // RecursiveMutex class
  74. class RecursiveMutex
  75. {
  76. public:
  77. /*
  78. * Constructor.
  79. */
  80. RecursiveMutex() noexcept
  81. #ifdef DISTRHO_OS_WINDOWS
  82. : fSection()
  83. #else
  84. : fMutex()
  85. #endif
  86. {
  87. #ifdef DISTRHO_OS_WINDOWS
  88. InitializeCriticalSection(&fSection);
  89. #else
  90. pthread_mutexattr_t atts;
  91. pthread_mutexattr_init(&atts);
  92. pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE);
  93. pthread_mutex_init(&fMutex, &atts);
  94. pthread_mutexattr_destroy(&atts);
  95. #endif
  96. }
  97. /*
  98. * Destructor.
  99. */
  100. ~RecursiveMutex() noexcept
  101. {
  102. #ifdef DISTRHO_OS_WINDOWS
  103. DeleteCriticalSection(&fSection);
  104. #else
  105. pthread_mutex_destroy(&fMutex);
  106. #endif
  107. }
  108. /*
  109. * Lock the mutex.
  110. */
  111. void lock() const noexcept
  112. {
  113. #ifdef DISTRHO_OS_WINDOWS
  114. EnterCriticalSection(&fSection);
  115. #else
  116. pthread_mutex_lock(&fMutex);
  117. #endif
  118. }
  119. /*
  120. * Try to lock the mutex.
  121. * Returns true if successful.
  122. */
  123. bool tryLock() const noexcept
  124. {
  125. #ifdef DISTRHO_OS_WINDOWS
  126. return (TryEnterCriticalSection(&fSection) != FALSE);
  127. #else
  128. return (pthread_mutex_trylock(&fMutex) == 0);
  129. #endif
  130. }
  131. /*
  132. * Unlock the mutex.
  133. */
  134. void unlock() const noexcept
  135. {
  136. #ifdef DISTRHO_OS_WINDOWS
  137. LeaveCriticalSection(&fSection);
  138. #else
  139. pthread_mutex_unlock(&fMutex);
  140. #endif
  141. }
  142. private:
  143. #ifdef DISTRHO_OS_WINDOWS
  144. mutable CRITICAL_SECTION fSection;
  145. #else
  146. mutable pthread_mutex_t fMutex;
  147. #endif
  148. DISTRHO_PREVENT_HEAP_ALLOCATION
  149. DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex)
  150. };
  151. // -----------------------------------------------------------------------
  152. // Helper class to lock&unlock a mutex during a function scope.
  153. template <class Mutex>
  154. class ScopeLocker
  155. {
  156. public:
  157. ScopeLocker(const Mutex& mutex) noexcept
  158. : fMutex(mutex)
  159. {
  160. fMutex.lock();
  161. }
  162. ~ScopeLocker() noexcept
  163. {
  164. fMutex.unlock();
  165. }
  166. private:
  167. const Mutex& fMutex;
  168. DISTRHO_PREVENT_HEAP_ALLOCATION
  169. DISTRHO_DECLARE_NON_COPY_CLASS(ScopeLocker)
  170. };
  171. // -----------------------------------------------------------------------
  172. // Helper class to try-lock&unlock a mutex during a function scope.
  173. template <class Mutex>
  174. class ScopeTryLocker
  175. {
  176. public:
  177. ScopeTryLocker(const Mutex& mutex) noexcept
  178. : fMutex(mutex),
  179. fLocked(mutex.tryLock()) {}
  180. ~ScopeTryLocker() noexcept
  181. {
  182. if (fLocked)
  183. fMutex.unlock();
  184. }
  185. bool wasLocked() const noexcept
  186. {
  187. return fLocked;
  188. }
  189. bool wasNotLocked() const noexcept
  190. {
  191. return !fLocked;
  192. }
  193. private:
  194. const Mutex& fMutex;
  195. const bool fLocked;
  196. DISTRHO_PREVENT_HEAP_ALLOCATION
  197. DISTRHO_DECLARE_NON_COPY_CLASS(ScopeTryLocker)
  198. };
  199. // -----------------------------------------------------------------------
  200. // Helper class to unlock&lock a mutex during a function scope.
  201. template <class Mutex>
  202. class ScopeUnlocker
  203. {
  204. public:
  205. ScopeUnlocker(const Mutex& mutex) noexcept
  206. : fMutex(mutex)
  207. {
  208. fMutex.unlock();
  209. }
  210. ~ScopeUnlocker() noexcept
  211. {
  212. fMutex.lock();
  213. }
  214. private:
  215. const Mutex& fMutex;
  216. DISTRHO_PREVENT_HEAP_ALLOCATION
  217. DISTRHO_DECLARE_NON_COPY_CLASS(ScopeUnlocker)
  218. };
  219. // -----------------------------------------------------------------------
  220. // Define types
  221. typedef ScopeLocker<Mutex> MutexLocker;
  222. typedef ScopeLocker<RecursiveMutex> RecursiveMutexLocker;
  223. typedef ScopeTryLocker<Mutex> MutexTryLocker;
  224. typedef ScopeTryLocker<RecursiveMutex> RecursiveMutexTryLocker;
  225. typedef ScopeUnlocker<Mutex> MutexUnlocker;
  226. typedef ScopeUnlocker<RecursiveMutex> RecursiveMutexUnlocker;
  227. // -----------------------------------------------------------------------
  228. END_NAMESPACE_DISTRHO
  229. #endif // DISTRHO_MUTEX_HPP_INCLUDED