Leaked source code of windows server 2003
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.
 
 
 
 
 
 

219 lines
4.3 KiB

// ReadWriteLock.cpp: implementation of the CReadWriteLock class.
//
//////////////////////////////////////////////////////////////////////
#include "dncmni.h"
#undef DPF_MODNAME
#define DPF_MODNAME "CReadWriteLock::Initialize"
BOOL CReadWriteLock::Initialize()
{
DPF_ENTER();
#ifdef DPNBUILD_ONLYONETHREAD
m_fCritSecInited = TRUE;
#ifdef DBG
m_dwThreadID = 0;
#endif // DBG
#else // ! DPNBUILD_ONLYONETHREAD
m_lReaderCount = 0;
m_lWriterCount = 0;
m_fWriterMode = FALSE;
#ifdef DBG
m_dwWriteThread = 0;
#endif // DBG
if (DNInitializeCriticalSection(&m_csWrite))
{
m_fCritSecInited = TRUE;
}
else
{
// This is necessary in case the user calls Deinitialize.
m_fCritSecInited = FALSE;
}
#endif // ! DPNBUILD_ONLYONETHREAD
DPF_EXIT();
return m_fCritSecInited;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CReadWriteLock::Deinitialize"
VOID CReadWriteLock::Deinitialize()
{
#ifndef DPNBUILD_ONLYONETHREAD
#ifdef DBG
DWORD dwCount;
#endif // DBG
#endif // ! DPNBUILD_ONLYONETHREAD
DPF_ENTER();
#ifdef DPNBUILD_ONLYONETHREAD
if (m_fCritSecInited)
{
#ifdef DBG
DNASSERT(m_dwThreadID == 0);
#endif // DBG
m_fCritSecInited = FALSE;
}
#else // ! DPNBUILD_ONLYONETHREAD
#ifdef DBG
DNASSERT(FALSE == m_fWriterMode);
DNASSERT(0 == m_dwWriteThread);
#endif // DBG
// The counts are decremented after leaving the cs, so these should be
// or going to 0.
#ifdef DBG
dwCount = 0;
#endif // DBG
while (m_lReaderCount)
{
Sleep(0);
#ifdef DBG
dwCount++;
DNASSERT(dwCount < 500);
#endif // DBG
}
#ifdef DBG
dwCount = 0;
#endif // DBG
while (m_lWriterCount)
{
Sleep(0);
#ifdef DBG
dwCount++;
DNASSERT(dwCount < 500);
#endif // DBG
}
if (m_fCritSecInited)
{
DNDeleteCriticalSection(&m_csWrite);
}
#endif // ! DPNBUILD_ONLYONETHREAD
DPF_EXIT();
}
#undef DPF_MODNAME
#define DPF_MODNAME "CReadWriteLock::EnterReadLock"
void CReadWriteLock::EnterReadLock()
{
DPF_ENTER();
DNASSERT(m_fCritSecInited == TRUE);
#ifdef DPNBUILD_ONLYONETHREAD
#ifdef DBG
DNASSERT(m_dwThreadID == 0);
m_dwThreadID = GetCurrentThreadId();
#endif // DBG
#else // ! DPNBUILD_ONLYONETHREAD
// Increment the reader count
DNInterlockedIncrement(&m_lReaderCount);
// Is there a writer waiting?
// As long as there is even one writer waiting,
// Everybody waits on the critical section
if (m_lWriterCount)
{
// Rollback.
DNInterlockedDecrement(&m_lReaderCount);
// We are assured that if every reader is waiting
// on the crit-sec, then readercount will be 0.
DNEnterCriticalSection(&m_csWrite);
DNInterlockedIncrement(&m_lReaderCount);
DNLeaveCriticalSection(&m_csWrite);
}
#ifdef DBG
DNASSERT(GetCurrentThreadId() != m_dwWriteThread);
DNASSERT(FALSE == m_fWriterMode);
#endif // DBG
#endif // ! DPNBUILD_ONLYONETHREAD
DPF_EXIT();
}
#undef DPF_MODNAME
#define DPF_MODNAME "CReadWriteLock::LeaveLock"
void CReadWriteLock::LeaveLock()
{
DPF_ENTER();
DNASSERT(m_fCritSecInited == TRUE);
#ifdef DPNBUILD_ONLYONETHREAD
#ifdef DBG
DNASSERT(m_dwThreadID == GetCurrentThreadId());
m_dwThreadID = 0;
#endif // DBG
#else // ! DPNBUILD_ONLYONETHREAD
if (m_fWriterMode)
{
#ifdef DBG
DNASSERT(GetCurrentThreadId() == m_dwWriteThread);
m_dwWriteThread = 0;
#endif // DBG
m_fWriterMode = FALSE;
DNLeaveCriticalSection(&m_csWrite);
DNInterlockedDecrement(&m_lWriterCount);
}
else
{
DNInterlockedDecrement(&m_lReaderCount);
}
#endif // ! DPNBUILD_ONLYONETHREAD
DPF_EXIT();
}
#undef DPF_MODNAME
#define DPF_MODNAME "CReadWriteLock::EnterWriteLock"
void CReadWriteLock::EnterWriteLock()
{
DPF_ENTER();
DNASSERT(m_fCritSecInited == TRUE);
#ifdef DPNBUILD_ONLYONETHREAD
#ifdef DBG
DNASSERT(m_dwThreadID == 0);
m_dwThreadID = GetCurrentThreadId();
#endif // DBG
#else // ! DPNBUILD_ONLYONETHREAD
// No re-entrance allowed!
#ifdef DBG
DNASSERT(GetCurrentThreadId() != m_dwWriteThread);
#endif // DBG
DNInterlockedIncrement(&m_lWriterCount);
DNEnterCriticalSection(&m_csWrite);
while (m_lReaderCount)
{
Sleep(0);
}
DNASSERT(FALSE == m_fWriterMode);
m_fWriterMode = TRUE;
#ifdef DBG
m_dwWriteThread = GetCurrentThreadId();
#endif // DBG
#endif // ! DPNBUILD_ONLYONETHREAD
DPF_EXIT();
}