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.

150 lines
2.9KB

  1. //
  2. // detail/conditionally_enabled_mutex.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
  11. #define ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/detail/mutex.hpp"
  17. #include "asio/detail/noncopyable.hpp"
  18. #include "asio/detail/scoped_lock.hpp"
  19. #include "asio/detail/push_options.hpp"
  20. namespace asio {
  21. namespace detail {
  22. // Mutex adapter used to conditionally enable or disable locking.
  23. class conditionally_enabled_mutex
  24. : private noncopyable
  25. {
  26. public:
  27. // Helper class to lock and unlock a mutex automatically.
  28. class scoped_lock
  29. : private noncopyable
  30. {
  31. public:
  32. // Tag type used to distinguish constructors.
  33. enum adopt_lock_t { adopt_lock };
  34. // Constructor adopts a lock that is already held.
  35. scoped_lock(conditionally_enabled_mutex& m, adopt_lock_t)
  36. : mutex_(m),
  37. locked_(m.enabled_)
  38. {
  39. }
  40. // Constructor acquires the lock.
  41. explicit scoped_lock(conditionally_enabled_mutex& m)
  42. : mutex_(m)
  43. {
  44. if (m.enabled_)
  45. {
  46. mutex_.mutex_.lock();
  47. locked_ = true;
  48. }
  49. else
  50. locked_ = false;
  51. }
  52. // Destructor releases the lock.
  53. ~scoped_lock()
  54. {
  55. if (locked_)
  56. mutex_.mutex_.unlock();
  57. }
  58. // Explicitly acquire the lock.
  59. void lock()
  60. {
  61. if (mutex_.enabled_ && !locked_)
  62. {
  63. mutex_.mutex_.lock();
  64. locked_ = true;
  65. }
  66. }
  67. // Explicitly release the lock.
  68. void unlock()
  69. {
  70. if (locked_)
  71. {
  72. mutex_.unlock();
  73. locked_ = false;
  74. }
  75. }
  76. // Test whether the lock is held.
  77. bool locked() const
  78. {
  79. return locked_;
  80. }
  81. // Get the underlying mutex.
  82. asio::detail::mutex& mutex()
  83. {
  84. return mutex_.mutex_;
  85. }
  86. private:
  87. friend class conditionally_enabled_event;
  88. conditionally_enabled_mutex& mutex_;
  89. bool locked_;
  90. };
  91. // Constructor.
  92. explicit conditionally_enabled_mutex(bool enabled)
  93. : enabled_(enabled)
  94. {
  95. }
  96. // Destructor.
  97. ~conditionally_enabled_mutex()
  98. {
  99. }
  100. // Determine whether locking is enabled.
  101. bool enabled() const
  102. {
  103. return enabled_;
  104. }
  105. // Lock the mutex.
  106. void lock()
  107. {
  108. if (enabled_)
  109. mutex_.lock();
  110. }
  111. // Unlock the mutex.
  112. void unlock()
  113. {
  114. if (enabled_)
  115. mutex_.unlock();
  116. }
  117. private:
  118. friend class scoped_lock;
  119. friend class conditionally_enabled_event;
  120. asio::detail::mutex mutex_;
  121. const bool enabled_;
  122. };
  123. } // namespace detail
  124. } // namespace asio
  125. #include "asio/detail/pop_options.hpp"
  126. #endif // ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP