臨界領域読み出し操作クラスCRWcriticalSection
2858 ワード
class CRWCriticalSection
{
public:
explicit CRWCriticalSection();
~CRWCriticalSection();
public:
BOOL LockReader(unsigned int nTimeOut = INFINITE);
void UnlockReader();
BOOL LockWriter(unsigned int nTimeOut = INFINITE);
void UnlockWriter();
private:
/*****/
HANDLE m_hNobodyIsReading;
HANDLE m_hWritingMutex;
CRITICAL_SECTION m_csReading;
unsigned int m_nReaders;
CRWCriticalSection(const CRWCriticalSection& cs);
CRWCriticalSection& operator=(const CRWCriticalSection& cs);
};
CRWCriticalSection::CRWCriticalSection()
{
// Create the flag that indicates if somebody is reading the object
// initially, nobody is...
m_hNobodyIsReading = CreateEvent(NULL, TRUE, TRUE, NULL);
// Create a mutex indicating who is writing (only one)
m_hWritingMutex = CreateMutex(NULL, FALSE, NULL);
assert(m_hNobodyIsReading && m_hWritingMutex);
// Create the critical section for maintaining the number of readers
// it should not delay much (so no need to analyse for deadlocks)
InitializeCriticalSection(&m_csReading);
m_nReaders = 0;
}
CRWCriticalSection::~CRWCriticalSection()
{
CloseHandle(m_hNobodyIsReading);
CloseHandle(m_hWritingMutex);
DeleteCriticalSection(&m_csReading);
assert(m_nReaders == 0);
}
BOOL CRWCriticalSection::LockReader(unsigned int nTimeout)
{
// We make sure that nobody is writing
if (WaitForSingleObject(m_hWritingMutex, nTimeout) != WAIT_OBJECT_0)
return FALSE;
// We need a critical section to update the number of readers
EnterCriticalSection(&m_csReading);
{
m_nReaders++;
if (m_nReaders == 1)
{
// We must indicate that there are some readers
ResetEvent(m_hNobodyIsReading);
}
}
LeaveCriticalSection(&m_csReading);
// I release the mutex for writing that I do not need
ReleaseMutex(m_hWritingMutex);
return TRUE;
}
void CRWCriticalSection::UnlockReader()
{
// We need a critical section to update the number of readers
EnterCriticalSection(&m_csReading);
{
m_nReaders--;
if (m_nReaders == 0)
{
// We indicate that there are no more readers
SetEvent(m_hNobodyIsReading);
}
}
LeaveCriticalSection(&m_csReading);
}
BOOL CRWCriticalSection::LockWriter(unsigned int nTimeout)
{
// Only one writer at a time
if (WaitForSingleObject(m_hWritingMutex,nTimeout) != WAIT_OBJECT_0)
return FALSE;
// Wait for all readers to leave
if (WaitForSingleObject(m_hNobodyIsReading,nTimeout) != WAIT_OBJECT_0)
{
// We have waited too long, so we have to set the "Writing" mutex
ReleaseMutex(m_hWritingMutex);
return FALSE;
}
return TRUE;
}
void CRWCriticalSection::UnlockWriter()
{
// Let other readers and writers in
ReleaseMutex(m_hWritingMutex);
}