加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
gnmutex.h 4.97 KB
一键复制 编辑 原始数据 按行查看 历史
gaoqingfeng 提交于 2023-02-01 19:47 . update gnmutex.h
#pragma once
// standard locker for multi thread.
#if defined(WIN32) || defined(WIN64)
// windows mutex.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <assert.h>
#ifndef GNAPI
#define GNAPI __stdcall
#endif
#define mutex_t CRITICAL_SECTION
#define mutex_init(m) InitializeCriticalSection(m)
#define mutex_acquire(m) EnterCriticalSection(m)
#define mutex_release(m) LeaveCriticalSection(m)
#define mutex_destroy(m) DeleteCriticalSection(m)
#else
// Linux mutex.
#include <pthread.h>
#define GNAPI
#define mutex_t pthread_mutex_t
#define mutex_init(m) pthread_mutex_init(m, nullptr)
#define mutex_acquire(m) pthread_mutex_lock(m)
#define mutex_release(m) pthread_mutex_unlock(m)
#define mutex_destroy(m) pthread_mutex_destroy(m)
#endif
namespace KCP {
// interface of mutex.
class IGNMutex {
public:
virtual ~IGNMutex() {}
virtual void GNAPI Lock() = 0;
virtual void GNAPI Unlock() = 0;
virtual void GNAPI Release() = 0;
};
// locker
class CLocker : public IGNMutex {
public:
CLocker() {
mutex_init(&m_oCS);
}
virtual ~CLocker() {
mutex_destroy(&m_oCS);
}
virtual void GNAPI Lock() {
mutex_acquire(&m_oCS);
}
virtual void GNAPI Unlock() {
mutex_release(&m_oCS);
}
virtual void GNAPI Release() {
}
protected:
mutex_t m_oCS;
};
// ????
class CNonMutex : public IGNMutex {
public:
CNonMutex() {}
virtual ~CNonMutex() {}
public:
virtual void GNAPI Lock() {}
virtual void GNAPI Unlock() {}
virtual void GNAPI Release() {}
};
// ?????
template <typename MT = CNonMutex>
class CAutoLock {
public:
CAutoLock(MT& oLocker) : m_oLocker(oLocker) {
m_oLocker.Lock();
}
~CAutoLock() {
m_oLocker.Unlock();
}
protected:
MT& m_oLocker;
};
// rwlock
#if defined(WIN32) || defined(WIN64)
#define RWLOCK_IDLE 0
#define RWLOCK_R 0x01
#define RWLOCK_W 0x02
class CRWLock {
private:
int _st;
int _rlockCount;
int _rwaitingCount;
int _wwaitingCount;
HANDLE _ev;
CRITICAL_SECTION _stLock;
public:
CRWLock()
: _rlockCount(0),
_st(RWLOCK_IDLE),
_rwaitingCount(0),
_wwaitingCount(0) {
InitializeCriticalSection(&_stLock);
_ev = CreateEvent(nullptr, TRUE, FALSE, nullptr);
assert(_ev != INVALID_HANDLE_VALUE);
}
~CRWLock() {
DeleteCriticalSection(&_stLock);
CloseHandle(_ev);
}
public:
void rlock() {
bool isWaitReturn = false;
while (1) {
EnterCriticalSection(&_stLock);
if (isWaitReturn) {
--_rwaitingCount;
}
if (_st == RWLOCK_IDLE) {
_st = RWLOCK_R;
_rlockCount++;
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
break;
}
else if (_st == RWLOCK_R) {
if (_wwaitingCount > 0) {
++_rwaitingCount;
ResetEvent(_ev);
LeaveCriticalSection(&_stLock);
WaitForSingleObject(_ev, INFINITE);
isWaitReturn = true;
}
else {
++_rlockCount;
LeaveCriticalSection(&_stLock);
break;
}
}
else if (_st == RWLOCK_W) {
++_rwaitingCount;
ResetEvent(_ev);
//SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);
LeaveCriticalSection(&_stLock);
WaitForSingleObject(_ev, INFINITE);
isWaitReturn = true;
}
else {
assert(0);
break;
}
}
}
void wlock() {
bool isWaitReturn = false;
while (1) {
//WaitForSingleObject(_stLock, INFINITE);
EnterCriticalSection(&_stLock);
if (isWaitReturn) --_wwaitingCount;
if (_st == RWLOCK_IDLE) {
_st = RWLOCK_W;
LeaveCriticalSection(&_stLock);
break;
}
else {
++_wwaitingCount;
ResetEvent(_ev);
LeaveCriticalSection(&_stLock);
WaitForSingleObject(_ev, INFINITE);
isWaitReturn = true;
}
}
}
void unlock() {
// WaitForSingleObject(_stLock, INFINITE);
EnterCriticalSection(&_stLock);
if (_rlockCount > 0) {
--_rlockCount;
if (0 == _rlockCount) {
_st = RWLOCK_IDLE;
if (_wwaitingCount > 0 || _rwaitingCount > 0) {
SetEvent(_ev);
}
else {
/* ???? */
}
}
else {
/* ???ж??? */
}
}
else {
_st = RWLOCK_IDLE;
if (_wwaitingCount > 0 || _rwaitingCount > 0) {
SetEvent(_ev);
} else {
/* ???ж??? */
}
}
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
}
};
#else
class CRWLock { // Linux rwlock.
protected:
int m_rd_count;
int m_wr_count;
public:
CRWLock() :m_rd_count(0), m_wr_count(0) {
::pthread_rwlock_init(&m_rwlock, nullptr);
}
~CRWLock() {
::pthread_rwlock_destroy(&m_rwlock);
}
inline void rdlock() {
::pthread_rwlock_rdlock(&m_rwlock);
++m_rd_count;
};
inline void wrlock() {
::pthread_rwlock_wrlock(&m_rwlock);
++m_wr_count;
++m_rd_count;
}
inline void unlock() {
::pthread_rwlock_unlock(&m_rwlock);
--m_rd_count;
}
private:
pthread_rwlock_t m_rwlock; /**< ????д?? */
};
#endif
// common mutex module
IGNMutex* GNAPI GetGNMutex();
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化