windows-nt/Source/XPSP1/NT/base/ntos/config/cmsubs3.c
2020-09-26 16:20:57 +08:00

304 lines
5.1 KiB
C

/*++
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