You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
2.8 KiB
142 lines
2.8 KiB
6 years ago
|
#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
|