aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/threads.h61
1 files changed, 60 insertions, 1 deletions
diff --git a/common/threads.h b/common/threads.h
index 2d1b4e7f..7fbe20cd 100644
--- a/common/threads.h
+++ b/common/threads.h
@@ -262,7 +262,66 @@ int altimespec_get(struct timespec *ts, int base);
void al_nssleep(unsigned long nsec);
#ifdef __cplusplus
-}
+} // extern "C"
+
+#include <mutex>
+
+/* Add specializations for std::lock_guard and std::unique_lock which take an
+ * almtx_t and call the appropriate almtx_* functions.
+ */
+namespace std {
+
+template<>
+class lock_guard<almtx_t> {
+ almtx_t &mMtx;
+
+public:
+ using mutex_type = almtx_t;
+
+ explicit lock_guard(almtx_t &mtx) : mMtx(mtx) { almtx_lock(&mMtx); }
+ lock_guard(almtx_t &mtx, std::adopt_lock_t) : mMtx(mtx) { }
+ ~lock_guard() { almtx_unlock(&mMtx); }
+
+ lock_guard(const lock_guard&) = delete;
+ lock_guard& operator=(const lock_guard&) = delete;
+};
+
+template<>
+class unique_lock<almtx_t> {
+ almtx_t *mMtx{nullptr};
+ bool mLocked{false};
+
+public:
+ using mutex_type = almtx_t;
+
+ explicit unique_lock(almtx_t &mtx) : mMtx(&mtx) { almtx_lock(mMtx); mLocked = true; }
+ unique_lock(unique_lock&& rhs) : mMtx(rhs.mMtx), mLocked(rhs.mLocked)
+ { rhs.mMtx = nullptr; rhs.mLocked = false; }
+ ~unique_lock() { if(mLocked) almtx_unlock(mMtx); }
+
+ unique_lock& operator=(const unique_lock&) = delete;
+ unique_lock& operator=(unique_lock&& rhs)
+ {
+ if(mLocked)
+ almtx_unlock(mMtx);
+ mMtx = rhs.mMtx; rhs.mMtx = nullptr;
+ mLocked = rhs.mLocked; rhs.mLocked = false;
+ return *this;
+ }
+
+ void lock()
+ {
+ almtx_lock(mMtx);
+ mLocked = true;
+ }
+ void unlock()
+ {
+ mLocked = false;
+ almtx_unlock(mMtx);
+ }
+};
+
+} // namespace std
#endif
#endif /* AL_THREADS_H */