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.

66 lines
1.4KB

  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. */
  9. struct SharedMutex {
  10. pthread_rwlock_t rwlock;
  11. SharedMutex() {
  12. if (pthread_rwlock_init(&rwlock, NULL))
  13. throw Exception("pthread_rwlock_init failed");
  14. }
  15. ~SharedMutex() {
  16. pthread_rwlock_destroy(&rwlock);
  17. }
  18. void lock() {
  19. if (pthread_rwlock_rdlock(&rwlock))
  20. throw Exception("pthread_rwlock_rdlock failed");
  21. }
  22. /** Returns whether the lock was acquired. */
  23. bool try_lock() {
  24. return pthread_rwlock_tryrdlock(&rwlock) == 0;
  25. }
  26. void unlock() {
  27. if (pthread_rwlock_unlock(&rwlock))
  28. throw Exception("pthread_rwlock_unlock failed");
  29. }
  30. void lock_shared() {
  31. if (pthread_rwlock_wrlock(&rwlock))
  32. throw Exception("pthread_rwlock_wrlock failed");
  33. }
  34. /** Returns whether the lock was acquired. */
  35. bool try_lock_shared() {
  36. return pthread_rwlock_trywrlock(&rwlock) == 0;
  37. }
  38. void unlock_shared() {
  39. if (pthread_rwlock_unlock(&rwlock))
  40. throw Exception("pthread_rwlock_unlock failed");
  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