diff options
Diffstat (limited to 'common/threads.h')
-rw-r--r-- | common/threads.h | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/common/threads.h b/common/threads.h index b0bebd8d..7fbe20cd 100644 --- a/common/threads.h +++ b/common/threads.h @@ -130,13 +130,21 @@ inline int altss_set(altss_t tss_id, void *val) #include <stdint.h> #include <errno.h> #include <pthread.h> +#ifdef __APPLE__ +#include <dispatch/dispatch.h> +#else /* !__APPLE__ */ #include <semaphore.h> +#endif /* __APPLE__ */ typedef pthread_t althrd_t; typedef pthread_mutex_t almtx_t; typedef pthread_cond_t alcnd_t; +#ifdef __APPLE__ +typedef dispatch_semaphore_t alsem_t; +#else /* !__APPLE__ */ typedef sem_t alsem_t; +#endif /* __APPLE__ */ typedef pthread_key_t altss_t; typedef pthread_once_t alonce_flag; @@ -254,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 */ |