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.

227 lines
4.8KB

  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. // -----------------------------------------------------------------------
  25. // Mutex class
  26. class Mutex
  27. {
  28. public:
  29. /*
  30. * Constructor.
  31. */
  32. Mutex() noexcept
  33. {
  34. pthread_mutex_init(&fMutex, nullptr);
  35. }
  36. /*
  37. * Destructor.
  38. */
  39. ~Mutex() noexcept
  40. {
  41. pthread_mutex_destroy(&fMutex);
  42. }
  43. /*
  44. * Lock the mutex.
  45. */
  46. void lock() const noexcept
  47. {
  48. pthread_mutex_lock(&fMutex);
  49. }
  50. /*
  51. * Try to lock the mutex.
  52. * Returns true if successful.
  53. */
  54. bool tryLock() const noexcept
  55. {
  56. return (pthread_mutex_trylock(&fMutex) == 0);
  57. }
  58. /*
  59. * Unlock the mutex.
  60. */
  61. void unlock() const noexcept
  62. {
  63. pthread_mutex_unlock(&fMutex);
  64. }
  65. private:
  66. mutable pthread_mutex_t fMutex;
  67. DISTRHO_PREVENT_HEAP_ALLOCATION
  68. DISTRHO_DECLARE_NON_COPY_CLASS(Mutex)
  69. };
  70. // -----------------------------------------------------------------------
  71. // RecursiveMutex class
  72. class RecursiveMutex
  73. {
  74. public:
  75. /*
  76. * Constructor.
  77. */
  78. RecursiveMutex() noexcept
  79. {
  80. #ifdef DISTRHO_OS_WINDOWS
  81. InitializeCriticalSection(&fSection);
  82. #else
  83. pthread_mutexattr_t atts;
  84. pthread_mutexattr_init(&atts);
  85. pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE);
  86. pthread_mutex_init(&fMutex, &atts);
  87. pthread_mutexattr_destroy(&atts);
  88. #endif
  89. }
  90. /*
  91. * Destructor.
  92. */
  93. ~RecursiveMutex() noexcept
  94. {
  95. #ifdef DISTRHO_OS_WINDOWS
  96. DeleteCriticalSection(&fSection);
  97. #else
  98. pthread_mutex_destroy(&fMutex);
  99. #endif
  100. }
  101. /*
  102. * Lock the mutex.
  103. */
  104. void lock() const noexcept
  105. {
  106. #ifdef DISTRHO_OS_WINDOWS
  107. EnterCriticalSection(&fSection);
  108. #else
  109. pthread_mutex_lock(&fMutex);
  110. #endif
  111. }
  112. /*
  113. * Try to lock the mutex.
  114. * Returns true if successful.
  115. */
  116. bool tryLock() const noexcept
  117. {
  118. #ifdef DISTRHO_OS_WINDOWS
  119. return (TryEnterCriticalSection(&fSection) != FALSE);
  120. #else
  121. return (pthread_mutex_trylock(&fMutex) == 0);
  122. #endif
  123. }
  124. /*
  125. * Unlock the mutex.
  126. */
  127. void unlock() const noexcept
  128. {
  129. #ifdef DISTRHO_OS_WINDOWS
  130. LeaveCriticalSection(&fSection);
  131. #else
  132. pthread_mutex_unlock(&fMutex);
  133. #endif
  134. }
  135. private:
  136. #ifdef DISTRHO_OS_WINDOWS
  137. mutable CRITICAL_SECTION fSection;
  138. #else
  139. mutable pthread_mutex_t fMutex;
  140. #endif
  141. DISTRHO_PREVENT_HEAP_ALLOCATION
  142. DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex)
  143. };
  144. // -----------------------------------------------------------------------
  145. // Helper class to lock&unlock a mutex during a function scope.
  146. template <class Mutex>
  147. class ScopedLocker
  148. {
  149. public:
  150. ScopedLocker(const Mutex& mutex) noexcept
  151. : fMutex(mutex)
  152. {
  153. fMutex.lock();
  154. }
  155. ~ScopedLocker() noexcept
  156. {
  157. fMutex.unlock();
  158. }
  159. private:
  160. const Mutex& fMutex;
  161. DISTRHO_PREVENT_HEAP_ALLOCATION
  162. DISTRHO_DECLARE_NON_COPY_CLASS(ScopedLocker)
  163. };
  164. // -----------------------------------------------------------------------
  165. // Helper class to unlock&lock a mutex during a function scope.
  166. template <class Mutex>
  167. class ScopedUnlocker
  168. {
  169. public:
  170. ScopedUnlocker(const Mutex& mutex) noexcept
  171. : fMutex(mutex)
  172. {
  173. fMutex.unlock();
  174. }
  175. ~ScopedUnlocker() noexcept
  176. {
  177. fMutex.lock();
  178. }
  179. private:
  180. const Mutex& fMutex;
  181. DISTRHO_PREVENT_HEAP_ALLOCATION
  182. DISTRHO_DECLARE_NON_COPY_CLASS(ScopedUnlocker)
  183. };
  184. // -----------------------------------------------------------------------
  185. // Define types
  186. typedef ScopedLocker<Mutex> MutexLocker;
  187. typedef ScopedLocker<RecursiveMutex> RecursiveMutexLocker;
  188. typedef ScopedUnlocker<Mutex> MutexUnlocker;
  189. typedef ScopedUnlocker<RecursiveMutex> RecursiveMutexUnlocker;
  190. // -----------------------------------------------------------------------
  191. #endif // DISTRHO_MUTEX_HPP_INCLUDED