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.

255 lines
5.4KB

  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. // CarlaCriticalSection class
  83. class CarlaCriticalSection
  84. {
  85. public:
  86. /*
  87. * Constructor.
  88. */
  89. CarlaCriticalSection() 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. ~CarlaCriticalSection() noexcept
  108. {
  109. #ifdef CARLA_OS_WIN
  110. DeleteCriticalSection(&fSection);
  111. #else
  112. pthread_mutex_destroy(&fMutex);
  113. #endif
  114. }
  115. /*
  116. * Enter section.
  117. */
  118. void enter() const noexcept
  119. {
  120. #ifdef CARLA_OS_WIN
  121. EnterCriticalSection(&fSection);
  122. #else
  123. pthread_mutex_lock(&fMutex);
  124. #endif
  125. }
  126. /*
  127. * Try-Enter section.
  128. */
  129. bool tryEnter() const noexcept
  130. {
  131. #ifdef CARLA_OS_WIN
  132. return (TryEnterCriticalSection(&fSection) != FALSE);
  133. #else
  134. return (pthread_mutex_trylock(&fMutex) == 0);
  135. #endif
  136. }
  137. /*
  138. * Leave section.
  139. */
  140. void leave() const noexcept
  141. {
  142. #ifdef CARLA_OS_WIN
  143. LeaveCriticalSection(&fSection);
  144. #else
  145. pthread_mutex_unlock(&fMutex);
  146. #endif
  147. }
  148. private:
  149. #ifdef CARLA_OS_WIN
  150. mutable CRITICAL_SECTION fSection;
  151. #else
  152. mutable pthread_mutex_t fMutex;
  153. #endif
  154. CARLA_PREVENT_HEAP_ALLOCATION
  155. CARLA_DECLARE_NON_COPY_CLASS(CarlaCriticalSection)
  156. };
  157. // -----------------------------------------------------------------------
  158. // Helper class to lock&unlock a mutex during a function scope.
  159. class CarlaMutexLocker
  160. {
  161. public:
  162. CarlaMutexLocker(const CarlaMutex& mutex) noexcept
  163. : fMutex(mutex)
  164. {
  165. fMutex.lock();
  166. }
  167. ~CarlaMutexLocker() noexcept
  168. {
  169. fMutex.unlock();
  170. }
  171. private:
  172. const CarlaMutex& fMutex;
  173. CARLA_PREVENT_HEAP_ALLOCATION
  174. CARLA_DECLARE_NON_COPY_CLASS(CarlaMutexLocker)
  175. };
  176. // -----------------------------------------------------------------------
  177. // Helper class to unlock&lock a mutex during a function scope.
  178. class CarlaMutexUnlocker
  179. {
  180. public:
  181. CarlaMutexUnlocker(const CarlaMutex& mutex) noexcept
  182. : fMutex(mutex)
  183. {
  184. fMutex.unlock();
  185. }
  186. ~CarlaMutexUnlocker() noexcept
  187. {
  188. fMutex.lock();
  189. }
  190. private:
  191. const CarlaMutex& fMutex;
  192. CARLA_PREVENT_HEAP_ALLOCATION
  193. CARLA_DECLARE_NON_COPY_CLASS(CarlaMutexUnlocker)
  194. };
  195. // -----------------------------------------------------------------------
  196. // Helper class to enter&leave during a function scope.
  197. class CarlaCriticalSectionScope
  198. {
  199. public:
  200. CarlaCriticalSectionScope(const CarlaCriticalSection& cs) noexcept
  201. : fSection(cs)
  202. {
  203. fSection.enter();
  204. }
  205. ~CarlaCriticalSectionScope() noexcept
  206. {
  207. fSection.leave();
  208. }
  209. private:
  210. const CarlaCriticalSection& fSection;
  211. CARLA_PREVENT_HEAP_ALLOCATION
  212. CARLA_DECLARE_NON_COPY_CLASS(CarlaCriticalSectionScope)
  213. };
  214. // -----------------------------------------------------------------------
  215. #endif // CARLA_MUTEX_HPP_INCLUDED