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.
|
|
/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
mrswlock.c
Abstract:
This module contains multiple readers / single writer implementation.
Author:
abhisheV 18-October-2001
Environment
User Level: Win32
Revision History:
--*/
#include "precomp.h"
DWORD InitializeRWLock( PWZC_RW_LOCK pWZCRWLock ) { DWORD dwError = 0; SECURITY_ATTRIBUTES SecurityAttributes;
memset(pWZCRWLock, 0, sizeof(WZC_RW_LOCK));
__try { InitializeCriticalSection(&(pWZCRWLock->csExclusive)); pWZCRWLock->bInitExclusive = TRUE; } __except (EXCEPTION_EXECUTE_HANDLER) { dwError = GetExceptionCode(); BAIL_ON_WIN32_ERROR(dwError); }
__try { InitializeCriticalSection(&(pWZCRWLock->csShared)); pWZCRWLock->bInitShared = TRUE; } __except (EXCEPTION_EXECUTE_HANDLER) { dwError = GetExceptionCode(); BAIL_ON_WIN32_ERROR(dwError); }
memset(&SecurityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
SecurityAttributes.nLength = sizeof(SecurityAttributes); SecurityAttributes.lpSecurityDescriptor = NULL; SecurityAttributes.bInheritHandle = TRUE;
pWZCRWLock->hReadDone = CreateEvent( &SecurityAttributes, TRUE, FALSE, NULL ); if (!pWZCRWLock->hReadDone) { dwError = GetLastError(); BAIL_ON_WIN32_ERROR(dwError); }
SetEvent(pWZCRWLock->hReadDone);
return (dwError);
error:
DestroyRWLock(pWZCRWLock);
return (dwError); }
VOID DestroyRWLock( PWZC_RW_LOCK pWZCRWLock ) { if (pWZCRWLock->hReadDone) { CloseHandle(pWZCRWLock->hReadDone); }
if (pWZCRWLock->bInitShared == TRUE) { DeleteCriticalSection(&(pWZCRWLock->csShared)); pWZCRWLock->bInitShared = FALSE; }
if (pWZCRWLock->bInitExclusive == TRUE) { DeleteCriticalSection(&(pWZCRWLock->csExclusive)); pWZCRWLock->bInitExclusive = FALSE; }
memset(pWZCRWLock, 0, sizeof(WZC_RW_LOCK));
return; }
VOID AcquireSharedLock( PWZC_RW_LOCK pWZCRWLock ) { //
// Claim the exclusive critical section. This call blocks if there's
// an active writer or if there's a writer waiting for active readers
// to complete.
//
EnterCriticalSection(&(pWZCRWLock->csExclusive));
//
// Claim access to the reader count. If this blocks, it's only for a
// brief moment while other reader threads go through to increment or
// decrement the reader count.
//
EnterCriticalSection(&(pWZCRWLock->csShared));
//
// Increment the reader count. If this is the first reader then reset
// the read done event so that the next writer blocks.
//
if ((pWZCRWLock->lReaders)++ == 0) { ResetEvent(pWZCRWLock->hReadDone); }
//
// Release access to the reader count.
//
LeaveCriticalSection(&(pWZCRWLock->csShared));
//
// Release access to the exclusive critical section. This enables
// other readers to come through and the next write to wait for
// active readers to complete which in turn prevents new readers
// from entering.
//
LeaveCriticalSection(&(pWZCRWLock->csExclusive));
return; }
VOID AcquireExclusiveLock( PWZC_RW_LOCK pWZCRWLock ) { DWORD dwStatus = 0;
//
// Claim the exclusive critical section. This not only prevents other
// threads from claiming the write lock, but also prevents any new
// threads from claiming the read lock.
//
EnterCriticalSection(&(pWZCRWLock->csExclusive));
pWZCRWLock->dwCurExclusiveOwnerThreadId = GetCurrentThreadId();
//
// Wait for the active readers to release their read locks.
//
dwStatus = WaitForSingleObject(pWZCRWLock->hReadDone, INFINITE);
ASSERT(dwStatus == WAIT_OBJECT_0);
return; }
VOID ReleaseSharedLock( PWZC_RW_LOCK pWZCRWLock ) { //
// Claim access to the reader count. If this blocks, it's only for a
// brief moment while other reader threads go through to increment or
// decrement the reader count.
//
EnterCriticalSection(&(pWZCRWLock->csShared));
//
// Decrement the reader count. If this is the last reader, set read
// done event, which allows the first waiting writer to proceed.
//
if (--(pWZCRWLock->lReaders) == 0) { SetEvent(pWZCRWLock->hReadDone); }
//
// Release access to the reader count.
//
LeaveCriticalSection(&(pWZCRWLock->csShared));
return; }
VOID ReleaseExclusiveLock( PWZC_RW_LOCK pWZCRWLock ) { //
// Make the exclusive critical section available to one other writer
// or to the first reader.
//
pWZCRWLock->dwCurExclusiveOwnerThreadId = 0;
LeaveCriticalSection(&(pWZCRWLock->csExclusive));
return; }
|