github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/cybozu/mutex.hpp (about) 1 #pragma once 2 /** 3 @file 4 @brief mutex 5 6 @author MITSUNARI Shigeo(@herumi) 7 @author MITSUNARI Shigeo 8 */ 9 10 #ifdef _WIN32 11 #include <windows.h> 12 #else 13 #include <pthread.h> 14 #include <time.h> 15 #endif 16 #include <assert.h> 17 #include <stdlib.h> 18 19 namespace cybozu { 20 21 class ConditionVariable; 22 23 namespace thread { 24 25 #ifdef _WIN32 26 typedef HANDLE MutexHandle; 27 inline void MutexInit(MutexHandle& mutex) 28 { 29 // mutex = CreateSemaphore(NULL /* no security */, 1 /* init */, 0x7FFFFFFF /* max */, NULL /* no name */); 30 mutex = CreateMutex(NULL /* no security */, FALSE /* no owner */, NULL /* no name */); 31 } 32 inline void MutexLock(MutexHandle& mutex) { WaitForSingleObject(mutex, INFINITE); } 33 /* 34 return false if timeout 35 @param msec [in] msec 36 */ 37 inline bool MutexLockTimeout(MutexHandle& mutex, int msec) 38 { 39 DWORD ret = WaitForSingleObject(mutex, msec); 40 if (ret == WAIT_OBJECT_0) { 41 return true; 42 } 43 if (ret == WAIT_TIMEOUT) { 44 return false; 45 } 46 /* ret == WAIT_ABANDONED */ 47 assert(0); 48 return false; 49 } 50 inline void MutexUnlock(MutexHandle& mutex) 51 { 52 // ReleaseSemaphore(mutex, 1, NULL); 53 ReleaseMutex(mutex); 54 } 55 inline void MutexTerm(MutexHandle& mutex) { CloseHandle(mutex); } 56 #else 57 typedef pthread_mutex_t MutexHandle; 58 inline void MutexInit(MutexHandle& mutex) 59 { 60 #if 1 61 pthread_mutex_init(&mutex, NULL); 62 #else 63 pthread_mutexattr_t attr; 64 pthread_mutexattr_init(&attr); 65 if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_TIMED_NP)) { 66 perror("pthread_mutexattr_settype"); 67 exit(1); 68 } 69 pthread_mutex_init(&mutex, &attr); 70 pthread_mutexattr_destroy(&attr); 71 #endif 72 } 73 inline void MutexLock(MutexHandle& mutex) { pthread_mutex_lock(&mutex); } 74 #if 0 75 inline bool MutexLockTimeout(MutexHandle& mutex, int msec) 76 { 77 timespec absTime; 78 clock_gettime(CLOCK_REALTIME, &absTime); 79 absTime.tv_sec += msec / 1000; 80 absTime.tv_nsec += msec % 1000; 81 bool ret = pthread_mutex_timedlock(&mutex, &absTime) == 0; 82 return ret; 83 } 84 #endif 85 inline void MutexUnlock(MutexHandle& mutex) { pthread_mutex_unlock(&mutex); } 86 inline void MutexTerm(MutexHandle& mutex) { pthread_mutex_destroy(&mutex); } 87 #endif 88 89 template<class T> 90 class AutoLockT { 91 public: 92 explicit AutoLockT(T &t) 93 : t_(t) 94 { 95 t_.lock(); 96 } 97 ~AutoLockT() 98 { 99 t_.unlock(); 100 } 101 private: 102 T& t_; 103 AutoLockT& operator=(const AutoLockT&); 104 }; 105 106 } // cybozu::thread 107 108 class Mutex { 109 friend class cybozu::ConditionVariable; 110 public: 111 Mutex() 112 { 113 thread::MutexInit(hdl_); 114 } 115 ~Mutex() 116 { 117 thread::MutexTerm(hdl_); 118 } 119 void lock() 120 { 121 thread::MutexLock(hdl_); 122 } 123 #if 0 124 bool lockTimeout(int msec) 125 { 126 return thread::MutexLockTimeout(hdl_, msec); 127 } 128 #endif 129 void unlock() 130 { 131 thread::MutexUnlock(hdl_); 132 } 133 private: 134 Mutex(const Mutex&); 135 Mutex& operator=(const Mutex&); 136 thread::MutexHandle hdl_; 137 }; 138 139 typedef cybozu::thread::AutoLockT<cybozu::Mutex> AutoLock; 140 141 } // cybozu