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.

152 lines
3.4KB

  1. /*
  2. * Carla Mutex
  3. * Copyright (C) 2013 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_mutexattr_t atts;
  33. pthread_mutexattr_init(&atts);
  34. pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE);
  35. pthread_mutex_init(&fMutex, &atts);
  36. pthread_mutexattr_destroy(&atts);
  37. }
  38. /*
  39. * Destructor.
  40. */
  41. ~CarlaMutex() noexcept
  42. {
  43. pthread_mutex_destroy(&fMutex);
  44. }
  45. /*
  46. * Check if "tryLock()" was called before.
  47. */
  48. bool wasTryLockCalled() const noexcept
  49. {
  50. const bool ret(fTryLockWasCalled);
  51. fTryLockWasCalled = false;
  52. return ret;
  53. }
  54. /*
  55. * Lock the mutex.
  56. */
  57. void lock() const noexcept
  58. {
  59. pthread_mutex_lock(&fMutex);
  60. }
  61. /*
  62. * Try to lock the mutex.
  63. * Returns true if successful.
  64. */
  65. bool tryLock() const noexcept
  66. {
  67. fTryLockWasCalled = true;
  68. return (pthread_mutex_trylock(&fMutex) == 0);
  69. }
  70. /*
  71. * Unlock the mutex, optionally resetting the tryLock check.
  72. */
  73. void unlock(const bool resetTryLock = false) const noexcept
  74. {
  75. if (resetTryLock)
  76. fTryLockWasCalled = false;
  77. pthread_mutex_unlock(&fMutex);
  78. }
  79. /*
  80. * Helper class to lock&unlock a mutex during a function scope.
  81. */
  82. class ScopedLocker
  83. {
  84. public:
  85. ScopedLocker(CarlaMutex& mutex) noexcept
  86. : fMutex(mutex)
  87. {
  88. fMutex.lock();
  89. }
  90. ~ScopedLocker() noexcept
  91. {
  92. fMutex.unlock();
  93. }
  94. private:
  95. CarlaMutex& fMutex;
  96. CARLA_PREVENT_HEAP_ALLOCATION
  97. CARLA_DECLARE_NON_COPY_CLASS(ScopedLocker)
  98. };
  99. /*
  100. * Helper class to unlock&lock a mutex during a function scope.
  101. */
  102. class ScopedUnlocker
  103. {
  104. public:
  105. ScopedUnlocker(CarlaMutex& mutex) noexcept
  106. : fMutex(mutex)
  107. {
  108. fMutex.unlock();
  109. }
  110. ~ScopedUnlocker() noexcept
  111. {
  112. fMutex.lock();
  113. }
  114. private:
  115. CarlaMutex& fMutex;
  116. CARLA_PREVENT_HEAP_ALLOCATION
  117. CARLA_DECLARE_NON_COPY_CLASS(ScopedUnlocker)
  118. };
  119. private:
  120. mutable pthread_mutex_t fMutex; // The mutex
  121. mutable volatile bool fTryLockWasCalled; // true if "tryLock()" was called at least once
  122. CARLA_PREVENT_HEAP_ALLOCATION
  123. CARLA_DECLARE_NON_COPY_CLASS(CarlaMutex)
  124. };
  125. // -----------------------------------------------------------------------
  126. #endif // CARLA_MUTEX_HPP_INCLUDED