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.

68 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. assert(!err);
  15. }
  16. ~SharedMutex() {
  17. pthread_rwlock_destroy(&rwlock);
  18. }
  19. void lock() {
  20. int err = pthread_rwlock_wrlock(&rwlock);
  21. assert(!err);
  22. }
  23. /** Returns whether the lock was acquired. */
  24. bool try_lock() {
  25. return pthread_rwlock_trywrlock(&rwlock) == 0;
  26. }
  27. void unlock() {
  28. int err = pthread_rwlock_unlock(&rwlock);
  29. assert(!err);
  30. }
  31. void lock_shared() {
  32. int err = pthread_rwlock_rdlock(&rwlock);
  33. assert(!err);
  34. }
  35. /** Returns whether the lock was acquired. */
  36. bool try_lock_shared() {
  37. return pthread_rwlock_tryrdlock(&rwlock) == 0;
  38. }
  39. void unlock_shared() {
  40. unlock();
  41. }
  42. };
  43. template <class TMutex>
  44. struct SharedLock {
  45. TMutex& m;
  46. SharedLock(TMutex& m) : m(m) {
  47. m.lock_shared();
  48. }
  49. ~SharedLock() {
  50. m.unlock_shared();
  51. }
  52. };
  53. } // namespace rack