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.
|
|
/*++
Copyright (C) Microsoft Corporation, 1995 - 1999
Module Name:
Locks.cxx
Abstract:
Out of line methods for some of the syncronization classes defined in locks.hxx.
Author:
Mario Goertzel [MarioGo]
Revision History:
MarioGo 03-14-95 Moved from misc.cxx. MarioGo 01-27-96 Changed from busy (Sleep(0)) wait to event
--*/
#include "qmgrlibp.h"
#include <locks.hxx>
BOOL BITSInitializeCriticalSectionInternal( LPCRITICAL_SECTION lpCriticalSection ) { __try { InitializeCriticalSection( lpCriticalSection ); // SEC: REVIEWED 2002-03-28
} __except( ( GetExceptionCode() == STATUS_NO_MEMORY ) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ) { return FALSE; } return TRUE; }
void BITSIntializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection ) { if (!BITSInitializeCriticalSectionInternal( lpCriticalSection ) ) throw ComError( E_OUTOFMEMORY ); }
//
// CShareLock methods
//
CSharedLock::CSharedLock() { exclusive_owner = 0; writers = 0; hevent = INVALID_HANDLE_VALUE; // Flag in the d'tor
BITSIntializeCriticalSection( &lock );
hevent = CreateEvent(0, FALSE, FALSE, 0); // SEC: REVIEWED 2002-03-28
if (0 == hevent) { DeleteCriticalSection(&lock); throw ComError( E_OUTOFMEMORY ); } }
CSharedLock::~CSharedLock() { if (hevent != INVALID_HANDLE_VALUE) { DeleteCriticalSection(&lock);
if (hevent) CloseHandle(hevent); } }
void CSharedLock::LockShared() { readers++;
if (writers) { if ((readers--) == 0) { SetEvent(hevent); }
EnterCriticalSection(&lock); readers++; LeaveCriticalSection(&lock); }
exclusive_owner = 0; }
void CSharedLock::UnlockShared(void) { ASSERT((LONG)readers > 0); ASSERT(exclusive_owner == 0);
if ( (readers--) == 0 && writers) { SetEvent(hevent); } }
void CSharedLock::LockExclusive(void) { EnterCriticalSection(&lock);
writers++; while(readers) { WaitForSingleObject(hevent, INFINITE); } ASSERT(writers); exclusive_owner = GetCurrentThreadId(); }
void CSharedLock::UnlockExclusive(void) { ASSERT(HeldExclusive()); ASSERT(writers); writers--; exclusive_owner = 0; LeaveCriticalSection(&lock); }
void CSharedLock::Unlock() { // Either the lock is held exclusively by this thread or the thread
// has a shared lock. (or the caller has a bug).
if (HeldExclusive()) { UnlockExclusive(); } else { UnlockShared(); } }
void CSharedLock::ConvertToExclusive(void) { ASSERT((LONG)readers > 0); ASSERT(exclusive_owner == 0);
if ( (readers--) == 0 && writers ) SetEvent(hevent);
EnterCriticalSection(&lock); writers++; while(readers) { WaitForSingleObject(hevent, INFINITE); } ASSERT(writers); exclusive_owner = GetCurrentThreadId(); }
|