diff options
Diffstat (limited to 'vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp')
-rw-r--r-- | vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp new file mode 100644 index 000000000..acde6bcbf --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp @@ -0,0 +1,141 @@ +#pragma once +/** + @file + @brief mutex + + @author MITSUNARI Shigeo(@herumi) + @author MITSUNARI Shigeo +*/ + +#ifdef _WIN32 + #include <windows.h> +#else + #include <pthread.h> + #include <time.h> +#endif +#include <assert.h> +#include <stdlib.h> + +namespace cybozu { + +class ConditionVariable; + +namespace thread { + +#ifdef _WIN32 + typedef HANDLE MutexHandle; + inline void MutexInit(MutexHandle& mutex) + { +// mutex = CreateSemaphore(NULL /* no security */, 1 /* init */, 0x7FFFFFFF /* max */, NULL /* no name */); + mutex = CreateMutex(NULL /* no security */, FALSE /* no owner */, NULL /* no name */); + } + inline void MutexLock(MutexHandle& mutex) { WaitForSingleObject(mutex, INFINITE); } + /* + return false if timeout + @param msec [in] msec + */ + inline bool MutexLockTimeout(MutexHandle& mutex, int msec) + { + DWORD ret = WaitForSingleObject(mutex, msec); + if (ret == WAIT_OBJECT_0) { + return true; + } + if (ret == WAIT_TIMEOUT) { + return false; + } + /* ret == WAIT_ABANDONED */ + assert(0); + return false; + } + inline void MutexUnlock(MutexHandle& mutex) + { +// ReleaseSemaphore(mutex, 1, NULL); + ReleaseMutex(mutex); + } + inline void MutexTerm(MutexHandle& mutex) { CloseHandle(mutex); } +#else + typedef pthread_mutex_t MutexHandle; + inline void MutexInit(MutexHandle& mutex) + { +#if 1 + pthread_mutex_init(&mutex, NULL); +#else + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_TIMED_NP)) { + perror("pthread_mutexattr_settype"); + exit(1); + } + pthread_mutex_init(&mutex, &attr); + pthread_mutexattr_destroy(&attr); +#endif + } + inline void MutexLock(MutexHandle& mutex) { pthread_mutex_lock(&mutex); } +#if 0 + inline bool MutexLockTimeout(MutexHandle& mutex, int msec) + { + timespec absTime; + clock_gettime(CLOCK_REALTIME, &absTime); + absTime.tv_sec += msec / 1000; + absTime.tv_nsec += msec % 1000; + bool ret = pthread_mutex_timedlock(&mutex, &absTime) == 0; + return ret; + } +#endif + inline void MutexUnlock(MutexHandle& mutex) { pthread_mutex_unlock(&mutex); } + inline void MutexTerm(MutexHandle& mutex) { pthread_mutex_destroy(&mutex); } +#endif + +template<class T> +class AutoLockT { +public: + explicit AutoLockT(T &t) + : t_(t) + { + t_.lock(); + } + ~AutoLockT() + { + t_.unlock(); + } +private: + T& t_; + AutoLockT& operator=(const AutoLockT&); +}; + +} // cybozu::thread + +class Mutex { + friend class cybozu::ConditionVariable; +public: + Mutex() + { + thread::MutexInit(hdl_); + } + ~Mutex() + { + thread::MutexTerm(hdl_); + } + void lock() + { + thread::MutexLock(hdl_); + } +#if 0 + bool lockTimeout(int msec) + { + return thread::MutexLockTimeout(hdl_, msec); + } +#endif + void unlock() + { + thread::MutexUnlock(hdl_); + } +private: + Mutex(const Mutex&); + Mutex& operator=(const Mutex&); + thread::MutexHandle hdl_; +}; + +typedef cybozu::thread::AutoLockT<cybozu::Mutex> AutoLock; + +} // cybozu |