diff options
-rw-r--r-- | common/threads.h | 61 |
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 */ |