⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ce_rwmutex.cpp

📁 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 + -