📄 ce_rwmutex.cpp
字号:
// =================================================================================
// File : RWMutex.cpp
// Author : linzg
// Created : 2007-11-12
// CopyRight (C) linzg
// =================================================================================
// =================================================================================
// Include Header Files
#include "RWMutex.h"
// =================================================================================
// Micro Definition
// =================================================================================
// Class Definition
// = Default constructor.
RWMutex::RWMutex()
{
#if defined(_WIN32)
m_nRefCount = 0;
m_nWaitingReaders = 0;
m_nWaitingWriters = 0;
m_condRead.m_nWaiters = 0;
m_condRead.m_boradcast = 0;
m_condRead.m_hCond = ::CreateSemaphoreA(0, 0, 0x7fffffff, 0);
m_condRead.m_hDone = ::CreateEventA(0, 0, 0, 0);
m_condWrite.m_nWaiters = 0;
m_condWrite.m_boradcast = 0;
m_condWrite.m_hCond = ::CreateSemaphoreA(0, 0, 0x7fffffff, 0);
m_condWrite.m_hDone = ::CreateEventA(0, 0, 0, 0);
#elif defined(_LINUX)
pthread_rwlock_init(&m_rwLock, 0);
#endif
}
// = Default destructor.
RWMutex::~RWMutex()
{
#if defined(_WIN32)
if (m_condRead.m_hCond)
::CloseHandle(m_condRead.m_hCond);
if (m_condRead.m_hDone)
::CloseHandle(m_condRead.m_hDone);
if (m_condWrite.m_hCond)
::CloseHandle(m_condWrite.m_hCond);
if (m_condWrite.m_hDone)
::CloseHandle(m_condWrite.m_hDone);
#elif defined(_LINUX)
pthread_rwlock_destroy(&m_rwLock);
#endif
}
// = Unlock.
void RWMutex::Unlock()
{
#if defined(_WIN32)
m_lock.Lock();
if (m_nRefCount > 0) // Releasing a reader.
m_nRefCount--;
else if (m_nRefCount == -1) // Releasing a writer.
m_nRefCount = 0;
if (m_nWaitingWriters > 0 && m_nRefCount == 0)
{
m_condWrite.m_lock.Lock();
int nHasWaiters = m_condWrite.m_nWaiters > 0;
m_condWrite.m_lock.Unlock();
if(nHasWaiters != 0)
::ReleaseSemaphore(m_condWrite.m_hCond, 1, 0);
}
else if (m_nWaitingReaders > 0 && m_nWaitingWriters == 0)
{
m_condRead.m_lock.Lock();
int nHasWaiters = 0;
if (m_condRead.m_nWaiters > 0)
{
m_condRead.m_boradcast = 1;
nHasWaiters = 1;
}
m_condRead.m_lock.Unlock();
if (nHasWaiters == 1)
{
::ReleaseSemaphore(m_condRead.m_hCond, m_condRead.m_nWaiters, 0);
::WaitForSingleObject(m_condRead.m_hDone, INFINITE);
m_condRead.m_boradcast = 0;
}
}
m_lock.Unlock();
#elif defined(_LINUX)
pthread_rwlock_unlock(&m_rwLock);
#endif
}
// = Lock read.
void RWMutex::LockRead()
{
#if defined(_WIN32)
m_lock.Lock();
while (m_nRefCount < 0 || m_nWaitingWriters > 0)
{
m_nWaitingReaders++;
m_lock.Unlock();
m_condRead.m_lock.Lock();
m_condRead.m_nWaiters++;
m_condRead.m_lock.Unlock();
::WaitForSingleObject(m_condRead.m_hCond, INFINITE); // WAIT_OBJECT_0
m_condRead.m_lock.Lock();
m_condRead.m_nWaiters--;
int nLastWaiter = m_condRead.m_boradcast && m_condRead.m_nWaiters == 0;
m_condRead.m_lock.Unlock();
if (nLastWaiter)
::SetEvent(m_condRead.m_hDone);
m_lock.Lock();
m_nWaitingReaders--;
}
m_nRefCount++;
m_lock.Unlock();
#elif defined(_LINUX)
pthread_rwlock_rdlock(&m_rwLock);
#endif
}
// = Lock write.
void RWMutex::LockWrite()
{
#if defined(_WIN32)
m_lock.Lock();
while (m_nRefCount != 0)
{
m_nWaitingWriters++;
m_lock.Unlock();
m_condWrite.m_lock.Lock();
m_condWrite.m_nWaiters++;
m_condWrite.m_lock.Unlock();
::WaitForSingleObject(m_condWrite.m_hCond, INFINITE); // WAIT_OBJECT_0
m_condWrite.m_lock.Lock();
m_condWrite.m_nWaiters--;
int nLastWaiter = m_condWrite.m_boradcast && m_condWrite.m_nWaiters == 0;
m_condWrite.m_lock.Unlock();
if (nLastWaiter)
::SetEvent(m_condWrite.m_hDone);
m_lock.Lock();
m_nWaitingWriters--;
}
m_nRefCount = -1;
m_lock.Unlock();
#elif defined(_LINUX)
pthread_rwlock_wrlock(&m_rwLock);
#endif
}
// =================================================================================
// 1.00 2007-11-12 Created By LinZaoGang
// File End
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -