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.

243 lines
5.3KB

  1. /*
  2. * Carla Mutex
  3. * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_MUTEX_HPP_INCLUDED
  18. #define CARLA_MUTEX_HPP_INCLUDED
  19. #include "CarlaUtils.hpp"
  20. #include <pthread.h>
  21. // -----------------------------------------------------------------------
  22. // CarlaMutex class
  23. class CarlaMutex
  24. {
  25. public:
  26. /*
  27. * Constructor.
  28. */
  29. CarlaMutex() noexcept
  30. : fTryLockWasCalled(false)
  31. {
  32. pthread_mutex_init(&fMutex, nullptr);
  33. }
  34. /*
  35. * Destructor.
  36. */
  37. ~CarlaMutex() noexcept
  38. {
  39. pthread_mutex_destroy(&fMutex);
  40. }
  41. /*
  42. * Check if "tryLock()" was called before.
  43. */
  44. bool wasTryLockCalled() const noexcept
  45. {
  46. const bool ret(fTryLockWasCalled);
  47. fTryLockWasCalled = false;
  48. return ret;
  49. }
  50. /*
  51. * Lock the mutex.
  52. */
  53. void lock() const noexcept
  54. {
  55. pthread_mutex_lock(&fMutex);
  56. }
  57. /*
  58. * Try to lock the mutex.
  59. * Returns true if successful.
  60. */
  61. bool tryLock() const noexcept
  62. {
  63. fTryLockWasCalled = true;
  64. return (pthread_mutex_trylock(&fMutex) == 0);
  65. }
  66. /*
  67. * Unlock the mutex, optionally resetting the tryLock check.
  68. */
  69. void unlock(const bool resetTryLock = false) const noexcept
  70. {
  71. if (resetTryLock)
  72. fTryLockWasCalled = false;
  73. pthread_mutex_unlock(&fMutex);
  74. }
  75. private:
  76. mutable pthread_mutex_t fMutex; // The mutex
  77. mutable volatile bool fTryLockWasCalled; // true if "tryLock()" was called at least once
  78. CARLA_PREVENT_HEAP_ALLOCATION
  79. CARLA_DECLARE_NON_COPY_CLASS(CarlaMutex)
  80. };
  81. // -----------------------------------------------------------------------
  82. // CarlaRecursiveMutex class
  83. class CarlaRecursiveMutex
  84. {
  85. public:
  86. /*
  87. * Constructor.
  88. */
  89. CarlaRecursiveMutex() noexcept
  90. {
  91. #ifdef CARLA_OS_WIN
  92. InitializeCriticalSection(&fSection);
  93. #else
  94. pthread_mutexattr_t atts;
  95. pthread_mutexattr_init(&atts);
  96. pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE);
  97. # ifndef CARLA_OS_ANDROID
  98. pthread_mutexattr_setprotocol(&atts, PTHREAD_PRIO_INHERIT);
  99. # endif
  100. pthread_mutex_init(&fMutex, &atts);
  101. pthread_mutexattr_destroy(&atts);
  102. #endif
  103. }
  104. /*
  105. * Destructor.
  106. */
  107. ~CarlaRecursiveMutex() noexcept
  108. {
  109. #ifdef CARLA_OS_WIN
  110. DeleteCriticalSection(&fSection);
  111. #else
  112. pthread_mutex_destroy(&fMutex);
  113. #endif
  114. }
  115. /*
  116. * Lock the mutex.
  117. */
  118. void lock() const noexcept
  119. {
  120. #ifdef CARLA_OS_WIN
  121. EnterCriticalSection(&fSection);
  122. #else
  123. pthread_mutex_lock(&fMutex);
  124. #endif
  125. }
  126. /*
  127. * Try to lock the mutex.
  128. * Returns true if successful.
  129. */
  130. bool tryLock() const noexcept
  131. {
  132. #ifdef CARLA_OS_WIN
  133. return (TryEnterCriticalSection(&fSection) != FALSE);
  134. #else
  135. return (pthread_mutex_trylock(&fMutex) == 0);
  136. #endif
  137. }
  138. /*
  139. * Unlock the mutex.
  140. */
  141. void unlock() const noexcept
  142. {
  143. #ifdef CARLA_OS_WIN
  144. LeaveCriticalSection(&fSection);
  145. #else
  146. pthread_mutex_unlock(&fMutex);
  147. #endif
  148. }
  149. private:
  150. #ifdef CARLA_OS_WIN
  151. mutable CRITICAL_SECTION fSection;
  152. #else
  153. mutable pthread_mutex_t fMutex;
  154. #endif
  155. CARLA_PREVENT_HEAP_ALLOCATION
  156. CARLA_DECLARE_NON_COPY_CLASS(CarlaRecursiveMutex)
  157. };
  158. // -----------------------------------------------------------------------
  159. // Helper class to lock&unlock a mutex during a function scope.
  160. template <class Mutex>
  161. class CarlaScopedLocker
  162. {
  163. public:
  164. CarlaScopedLocker(const Mutex& mutex) noexcept
  165. : fMutex(mutex)
  166. {
  167. fMutex.lock();
  168. }
  169. ~CarlaScopedLocker() noexcept
  170. {
  171. fMutex.unlock();
  172. }
  173. private:
  174. const Mutex& fMutex;
  175. CARLA_PREVENT_HEAP_ALLOCATION
  176. CARLA_DECLARE_NON_COPY_CLASS(CarlaScopedLocker)
  177. };
  178. // -----------------------------------------------------------------------
  179. // Helper class to unlock&lock a mutex during a function scope.
  180. template <class Mutex>
  181. class CarlaScopedUnlocker
  182. {
  183. public:
  184. CarlaScopedUnlocker(const Mutex& mutex) noexcept
  185. : fMutex(mutex)
  186. {
  187. fMutex.unlock();
  188. }
  189. ~CarlaScopedUnlocker() noexcept
  190. {
  191. fMutex.lock();
  192. }
  193. private:
  194. const Mutex& fMutex;
  195. CARLA_PREVENT_HEAP_ALLOCATION
  196. CARLA_DECLARE_NON_COPY_CLASS(CarlaScopedUnlocker)
  197. };
  198. // -----------------------------------------------------------------------
  199. // Define types
  200. typedef CarlaScopedLocker<CarlaMutex> CarlaMutexLocker;
  201. typedef CarlaScopedLocker<CarlaRecursiveMutex> CarlaRecursiveMutexLocker;
  202. typedef CarlaScopedUnlocker<CarlaMutex> CarlaMutexUnlocker;
  203. typedef CarlaScopedUnlocker<CarlaRecursiveMutex> CarlaRecursiveMutexUnlocker;
  204. // -----------------------------------------------------------------------
  205. #endif // CARLA_MUTEX_HPP_INCLUDED