From eb9a47610591808e865ec36219c1aac62fe03ff1 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Tue, 28 Dec 2021 10:06:18 -0500 Subject: [PATCH] Move ReadWriteMutex from Engine.cpp to new mutex.hpp header. --- include/mutex.hpp | 76 +++++++++++++++++++++++++++++++++++++++++++ include/rack.hpp | 1 + src/engine/Engine.cpp | 55 +------------------------------ 3 files changed, 78 insertions(+), 54 deletions(-) create mode 100644 include/mutex.hpp diff --git a/include/mutex.hpp b/include/mutex.hpp new file mode 100644 index 00000000..aa9811c6 --- /dev/null +++ b/include/mutex.hpp @@ -0,0 +1,76 @@ +#pragma once +#include +#include + + +namespace rack { + + +/** Allows multiple "reader" threads to obtain a lock simultaneously, but only one "writer" thread. +This implementation is currently just a wrapper for pthreads, which works on Linux/Mac/. +This is available in C++17 as std::shared_mutex, but unfortunately we're using C++11. +*/ +struct ReadWriteMutex { + pthread_rwlock_t rwlock; + + ReadWriteMutex() { + if (pthread_rwlock_init(&rwlock, NULL)) + throw Exception("pthread_rwlock_init failed"); + } + ~ReadWriteMutex() { + pthread_rwlock_destroy(&rwlock); + } + + void lockReader() { + if (pthread_rwlock_rdlock(&rwlock)) + throw Exception("pthread_rwlock_rdlock failed"); + } + /** Returns whether the lock was acquired. */ + bool tryLockReader() { + return pthread_rwlock_tryrdlock(&rwlock) == 0; + } + void unlockReader() { + if (pthread_rwlock_unlock(&rwlock)) + throw Exception("pthread_rwlock_unlock failed"); + } + + void lockWriter() { + if (pthread_rwlock_wrlock(&rwlock)) + throw Exception("pthread_rwlock_wrlock failed"); + } + /** Returns whether the lock was acquired. */ + bool tryLockWriter() { + return pthread_rwlock_trywrlock(&rwlock) == 0; + } + void unlockWriter() { + if (pthread_rwlock_unlock(&rwlock)) + throw Exception("pthread_rwlock_unlock failed"); + } +}; + + +struct ReadLock { + ReadWriteMutex& m; + + ReadLock(ReadWriteMutex& m) : m(m) { + m.lockReader(); + } + ~ReadLock() { + m.unlockReader(); + } +}; + + +struct WriteLock { + ReadWriteMutex& m; + + WriteLock(ReadWriteMutex& m) : m(m) { + m.lockWriter(); + } + ~WriteLock() { + m.unlockWriter(); + } +}; + + +} // namespace rack diff --git a/include/rack.hpp b/include/rack.hpp index a9ea5b40..33b467d3 100644 --- a/include/rack.hpp +++ b/include/rack.hpp @@ -23,6 +23,7 @@ Directly including Rack headers other than rack.hpp in your plugin is unsupporte #include #include #include +#include #include #include #include diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index ce473eab..30b75b0c 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -15,6 +14,7 @@ #include #include #include +#include namespace rack { @@ -31,59 +31,6 @@ static void initMXCSR() { } -/** Allows multiple "reader" threads to obtain a lock simultaneously, but only one "writer" thread. -This implementation is currently just a wrapper for pthreads, which works on Linux/Mac/. -This is available in C++17 as std::shared_mutex, but unfortunately we're using C++11. -*/ -struct ReadWriteMutex { - pthread_rwlock_t rwlock; - - ReadWriteMutex() { - if (pthread_rwlock_init(&rwlock, NULL)) - throw Exception("pthread_rwlock_init failed"); - } - ~ReadWriteMutex() { - pthread_rwlock_destroy(&rwlock); - } - void lockReader() { - if (pthread_rwlock_rdlock(&rwlock)) - throw Exception("pthread_rwlock_rdlock failed"); - } - void unlockReader() { - if (pthread_rwlock_unlock(&rwlock)) - throw Exception("pthread_rwlock_unlock failed"); - } - void lockWriter() { - if (pthread_rwlock_wrlock(&rwlock)) - throw Exception("pthread_rwlock_wrlock failed"); - } - void unlockWriter() { - if (pthread_rwlock_unlock(&rwlock)) - throw Exception("pthread_rwlock_unlock failed"); - } -}; - -struct ReadLock { - ReadWriteMutex& m; - ReadLock(ReadWriteMutex& m) : m(m) { - m.lockReader(); - } - ~ReadLock() { - m.unlockReader(); - } -}; - -struct WriteLock { - ReadWriteMutex& m; - WriteLock(ReadWriteMutex& m) : m(m) { - m.lockWriter(); - } - ~WriteLock() { - m.unlockWriter(); - } -}; - - /** Barrier based on mutexes. Not finished or tested, do not use. */