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.

72 lines
1.3KB

  1. #pragma once
  2. #include <common.hpp>
  3. #include <pthread.h>
  4. namespace rack {
  5. /** Allows multiple "reader" threads to obtain a lock simultaneously, but only one "writer" thread.
  6. This implementation is currently just a wrapper for pthreads, which works on Linux/Mac/.
  7. This is available in C++17 as std::shared_mutex, but unfortunately we're using C++11.
  8. Locking should be avoided in real-time audio threads.
  9. */
  10. struct SharedMutex {
  11. pthread_rwlock_t rwlock;
  12. SharedMutex() {
  13. int err = pthread_rwlock_init(&rwlock, NULL);
  14. (void) err;
  15. assert(!err);
  16. }
  17. ~SharedMutex() {
  18. pthread_rwlock_destroy(&rwlock);
  19. }
  20. void lock() {
  21. int err = pthread_rwlock_wrlock(&rwlock);
  22. (void) err;
  23. assert(!err);
  24. }
  25. /** Returns whether the lock was acquired. */
  26. bool try_lock() {
  27. return pthread_rwlock_trywrlock(&rwlock) == 0;
  28. }
  29. void unlock() {
  30. int err = pthread_rwlock_unlock(&rwlock);
  31. (void) err;
  32. assert(!err);
  33. }
  34. void lock_shared() {
  35. int err = pthread_rwlock_rdlock(&rwlock);
  36. (void) err;
  37. assert(!err);
  38. }
  39. /** Returns whether the lock was acquired. */
  40. bool try_lock_shared() {
  41. return pthread_rwlock_tryrdlock(&rwlock) == 0;
  42. }
  43. void unlock_shared() {
  44. unlock();
  45. }
  46. };
  47. template <class TMutex>
  48. struct SharedLock {
  49. TMutex& m;
  50. SharedLock(TMutex& m) : m(m) {
  51. m.lock_shared();
  52. }
  53. ~SharedLock() {
  54. m.unlock_shared();
  55. }
  56. };
  57. } // namespace rack