|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
cmsubs3.c
Abstract:
This module contains locking support routines for the configuration manager.
Author:
Bryan M. Willman (bryanwi) 30-Mar-1992
Revision History:
--*/
#include "cmp.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,CmpLockRegistry)
#pragma alloc_text(PAGE,CmpLockRegistryExclusive)
#pragma alloc_text(PAGE,CmpLockKCBTree)
#pragma alloc_text(PAGE,CmpLockKCBTreeExclusive)
#pragma alloc_text(PAGE,CmpUnlockRegistry)
#pragma alloc_text(PAGE,CmpUnlockKCBTree)
#if DBG
#pragma alloc_text(PAGE,CmpTestRegistryLock)
#pragma alloc_text(PAGE,CmpTestRegistryLockExclusive)
#pragma alloc_text(PAGE,CmpTestKCBLock)
#pragma alloc_text(PAGE,CmpTestKCBLockExclusive)
#endif
#endif
//
// Global registry lock
//
ERESOURCE CmpRegistryLock; ERESOURCE CmpKcbLock; ULONG CmpFlushStarveWriters = 0; BOOLEAN CmpFlushOnLockRelease = FALSE; LONG CmRegistryLogSizeLimit = -1;
#if DBG
PVOID CmpRegistryLockCaller; PVOID CmpRegistryLockCallerCaller; PVOID CmpKCBLockCaller; PVOID CmpKCBLockCallerCaller; #endif //DBG
extern BOOLEAN CmpSpecialBootCondition;
VOID CmpLockRegistry( VOID ) /*++
Routine Description:
Lock the registry for shared (read-only) access
Arguments:
None.
Return Value:
None, the registry lock will be held for shared access upon return.
--*/ { #if DBG
PVOID Caller; PVOID CallerCaller; #endif
KeEnterCriticalRegion();
if( CmpFlushStarveWriters ) { //
// a flush is in progress; starve potential writers
//
ExAcquireSharedStarveExclusive(&CmpRegistryLock, TRUE); } else { //
// regular shared mode
//
ExAcquireResourceSharedLite(&CmpRegistryLock, TRUE); }
#if DBG
RtlGetCallersAddress(&Caller, &CallerCaller); CmKdPrintEx((DPFLTR_CONFIG_ID,CML_LOCKING,"CmpLockRegistry: c, cc: %p %p\n", Caller, CallerCaller)); #endif
}
VOID CmpLockRegistryExclusive( VOID ) /*++
Routine Description:
Lock the registry for exclusive (write) access.
Arguments:
None.
Return Value:
TRUE - Lock was acquired exclusively
FALSE - Lock is owned by another thread.
--*/ { KeEnterCriticalRegion(); ExAcquireResourceExclusiveLite(&CmpRegistryLock,TRUE);
ASSERT( CmpFlushStarveWriters == 0 );
#if DBG
RtlGetCallersAddress(&CmpRegistryLockCaller, &CmpRegistryLockCallerCaller); #endif //DBG
}
VOID CmpUnlockRegistry( ) /*++
Routine Description:
Unlock the registry.
--*/ { ASSERT_CM_LOCK_OWNED();
//
// test if bit set to force flush; and we own the reglock exclusive and ownercount is 1
//
if( CmpFlushOnLockRelease && ExIsResourceAcquiredExclusiveLite(&CmpRegistryLock) && (CmpRegistryLock.OwnerThreads[0].OwnerCount == 1) ) { //
// we need to flush now
//
ASSERT_CM_LOCK_OWNED_EXCLUSIVE(); CmpDoFlushAll(TRUE); CmpFlushOnLockRelease = FALSE; } ExReleaseResourceLite(&CmpRegistryLock); KeLeaveCriticalRegion(); }
#if DBG
BOOLEAN CmpTestRegistryLock(VOID) { BOOLEAN rc;
rc = TRUE; if (ExIsResourceAcquiredShared(&CmpRegistryLock) == 0) { rc = FALSE; } return rc; }
BOOLEAN CmpTestRegistryLockExclusive(VOID) { if (ExIsResourceAcquiredExclusiveLite(&CmpRegistryLock) == 0) { return(FALSE); } return(TRUE); }
#endif
VOID CmpLockKCBTree( VOID ) /*++
Routine Description:
Lock the KCB tree for shared (read-only) access
Arguments:
None.
Return Value:
None, the kcb lock will be held for shared access upon return.
--*/ { #if DBG
PVOID Caller; PVOID CallerCaller; #endif
//
// we don't need to enter critical section here as we are already there
// (i.e. kcb lock can be aquired only while holding the registry lock)
//
ExAcquireResourceSharedLite(&CmpKcbLock, TRUE);
#if DBG
RtlGetCallersAddress(&Caller, &CallerCaller); CmKdPrintEx((DPFLTR_CONFIG_ID,CML_LOCKING,"CmpLockKCBTree: c, cc: %p %p\n", Caller, CallerCaller)); #endif
}
VOID CmpLockKCBTreeExclusive( VOID ) /*++
Routine Description:
Lock the KCB tree for exclusive (write) access.
Arguments:
None.
Return Value:
None, the kcb lock will be held for exclusive access upon return.
--*/ { //
// we don't need to enter critical section here as we are already there
// (i.e. kcb lock can be aquired only while holding the registry lock)
//
ExAcquireResourceExclusiveLite(&CmpKcbLock,TRUE); #if DBG
RtlGetCallersAddress(&CmpKCBLockCaller, &CmpKCBLockCallerCaller); #endif //DBG
}
VOID CmpUnlockKCBTree( ) /*++
Routine Description:
Unlock the KCB_TREE.
--*/ { ASSERT_KCB_LOCK_OWNED(); ExReleaseResourceLite(&CmpKcbLock); }
#if DBG
BOOLEAN CmpTestKCBLock(VOID) { BOOLEAN rc;
rc = TRUE; if (ExIsResourceAcquiredShared(&CmpKcbLock) == 0) { rc = FALSE; } return rc; }
BOOLEAN CmpTestKCBLockExclusive(VOID) { if (ExIsResourceAcquiredExclusiveLite(&CmpKcbLock) == 0) { return(FALSE); } return(TRUE); }
#endif
|