Source code of Windows XP (NT5)
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.
|
|
// this lock only works for a single write, and multiple read, concurrent
// multiple exclusive lock isn't a supported scenario
//
// (1) ClaimExclusiveLock() and ClaimShareLock() is mutually exclusive because
// the reverse order of increments and checking
//
// (2) As soon as Exclusive is set, all new Share lock will be blocked
//
//
#ifndef _CReadWriteLock_H_
#define _CReadWriteLock_H_
class CReadWriteLock { long lExclusive; long lTotalUsers; long lReadInQueue; HANDLE hWriteReadyEvent, hReadReadyEvent;
public: CReadWriteLock() { hWriteReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); hReadReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); };
~CReadWriteLock() { CloseHandle(hWriteReadyEvent); CloseHandle(hReadReadyEvent); }
bool IsInit() { return NULL != hWriteReadyEvent && NULL != hReadReadyEvent; }
bool CReadWriteLock::ClaimExclusiveLock() { ResetEvent(hWriteReadyEvent); ResetEvent(hReadReadyEvent); InterlockedIncrement( &lExclusive ); InterlockedIncrement( &lTotalUsers ); if (lTotalUsers > 1) { if (lReadInQueue > 0) // in case no body is in the read queue
{ // wait until all the reads to finish
if (WAIT_OBJECT_0 != WaitForSingleObject(hWriteReadyEvent, INFINITE)) return false; } } return true; }
void CReadWriteLock::ReleaseExclusiveLock( ) { InterlockedDecrement( &lTotalUsers ); InterlockedDecrement( &lExclusive ); SetEvent(hReadReadyEvent); }
bool CReadWriteLock::ClaimShareLock( ) { InterlockedIncrement( &lTotalUsers ); if (CReadWriteLock::lExclusive > 0) { if (WAIT_OBJECT_0 != WaitForSingleObject(hReadReadyEvent, INFINITE)) return false; } InterlockedIncrement ( &lReadInQueue ); return true; }
void CReadWriteLock::ReleaseShareLock( ) { if (0 == InterlockedDecrement ( &lReadInQueue )) { if (CReadWriteLock::lExclusive > 0) SetEvent(hWriteReadyEvent); } InterlockedDecrement( &lTotalUsers ); } };
//
// this class extends CReadWriteLock to allow multiple write threads
// -- additional overhead of entering/leaving critical section
//
class CReadWriteLockEx : public CReadWriteLock { public: bool ClaimExclusiveLock() { // Request ownership of the critical section.
EnterCriticalSection(&CriticalSection); return CReadWriteLock::ClaimExclusiveLock(); };
void ReleaseExclusiveLock( ) { CReadWriteLock::ReleaseExclusiveLock(); // Release ownership of the critical section.
LeaveCriticalSection(&CriticalSection); };
public: // constructor and desctructor
CReadWriteLockEx() { // Initialize the critical section.
InitializeCriticalSection(&CriticalSection); }; virtual ~CReadWriteLockEx() { // Release resources used by the critical section object.
DeleteCriticalSection(&CriticalSection); };
protected: // data members
CRITICAL_SECTION CriticalSection; };
#endif
|