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