mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 13:16:07 +00:00
[FLTMGR}
- Implement FltAcquirePushLockExclusive, FltAcquirePushLockShared and FltReleasePushLock. Lifted from ntos' internal pushlock routines. - Implement FltpObjectPointerReference and partially implement FltpObjectPointerDerference svn path=/trunk/; revision=74588
This commit is contained in:
parent
a652c58c19
commit
fb1948e7d4
1 changed files with 113 additions and 0 deletions
|
@ -20,7 +20,18 @@
|
||||||
|
|
||||||
/* DATA *********************************************************************/
|
/* DATA *********************************************************************/
|
||||||
|
|
||||||
|
#define ExpChangePushlock(x, y, z) InterlockedCompareExchangePointer((PVOID*)x, (PVOID)y, (PVOID)z)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pushlock bits
|
||||||
|
//
|
||||||
|
#define EX_PUSH_LOCK_LOCK_V ((ULONG_PTR)0x0)
|
||||||
|
#define EX_PUSH_LOCK_LOCK ((ULONG_PTR)0x1)
|
||||||
|
#define EX_PUSH_LOCK_WAITING ((ULONG_PTR)0x2)
|
||||||
|
#define EX_PUSH_LOCK_WAKING ((ULONG_PTR)0x4)
|
||||||
|
#define EX_PUSH_LOCK_MULTIPLE_SHARED ((ULONG_PTR)0x8)
|
||||||
|
#define EX_PUSH_LOCK_SHARE_INC ((ULONG_PTR)0x10)
|
||||||
|
#define EX_PUSH_LOCK_PTR_BITS ((ULONG_PTR)0xf)
|
||||||
|
|
||||||
/* EXPORTED FUNCTIONS ******************************************************/
|
/* EXPORTED FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
@ -45,6 +56,85 @@ FltObjectDereference(_Inout_ PVOID Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_Acquires_lock_(_Global_critical_region_)
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
FltAcquirePushLockExclusive(_Inout_ _Requires_lock_not_held_(*_Curr_) _Acquires_lock_(*_Curr_) PEX_PUSH_LOCK PushLock)
|
||||||
|
{
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
|
/* Try acquiring the lock */
|
||||||
|
if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V))
|
||||||
|
{
|
||||||
|
/* Someone changed it, use the slow path */
|
||||||
|
ExfAcquirePushLockExclusive(PushLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
FLT_ASSERT(PushLock->Locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_Acquires_lock_(_Global_critical_region_)
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
FltAcquirePushLockShared(_Inout_ _Requires_lock_not_held_(*_Curr_) _Acquires_lock_(*_Curr_) PEX_PUSH_LOCK PushLock)
|
||||||
|
{
|
||||||
|
EX_PUSH_LOCK NewValue;
|
||||||
|
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
|
/* Try acquiring the lock */
|
||||||
|
NewValue.Value = EX_PUSH_LOCK_LOCK | EX_PUSH_LOCK_SHARE_INC;
|
||||||
|
if (ExpChangePushlock(PushLock, NewValue.Ptr, 0))
|
||||||
|
{
|
||||||
|
/* Someone changed it, use the slow path */
|
||||||
|
ExfAcquirePushLockShared(PushLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity checks */
|
||||||
|
ASSERT(PushLock->Locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
_Releases_lock_(_Global_critical_region_)
|
||||||
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
|
VOID
|
||||||
|
FLTAPI
|
||||||
|
FltReleasePushLock(_Inout_ _Requires_lock_held_(*_Curr_) _Releases_lock_(*_Curr_) PEX_PUSH_LOCK PushLock)
|
||||||
|
{
|
||||||
|
EX_PUSH_LOCK OldValue = *PushLock;
|
||||||
|
EX_PUSH_LOCK NewValue;
|
||||||
|
|
||||||
|
/* Sanity checks */
|
||||||
|
FLT_ASSERT(OldValue.Locked);
|
||||||
|
|
||||||
|
/* Check if the pushlock is shared */
|
||||||
|
if (OldValue.Shared > 1)
|
||||||
|
{
|
||||||
|
/* Decrease the share count */
|
||||||
|
NewValue.Value = OldValue.Value - EX_PUSH_LOCK_SHARE_INC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Clear the pushlock entirely */
|
||||||
|
NewValue.Value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if nobody is waiting on us and try clearing the lock here */
|
||||||
|
if ((OldValue.Waiting) ||
|
||||||
|
(ExpChangePushlock(PushLock, NewValue.Ptr, OldValue.Ptr) !=
|
||||||
|
OldValue.Ptr))
|
||||||
|
{
|
||||||
|
/* We have waiters, use the long path */
|
||||||
|
ExfReleasePushLock(PushLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* INTERNAL FUNCTIONS ******************************************************/
|
/* INTERNAL FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
|
@ -157,3 +247,26 @@ FltpGetObjectName(_In_ PVOID Object,
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
FltpObjectPointerReference(_In_ PFLT_OBJECT Object)
|
||||||
|
{
|
||||||
|
PULONG Result;
|
||||||
|
|
||||||
|
/* Store the old count and increment */
|
||||||
|
Result = &Object->PointerCount;
|
||||||
|
InterlockedIncrement((PLONG)&Object->PointerCount);
|
||||||
|
|
||||||
|
/* Return the initial value */
|
||||||
|
return *Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FltpObjectPointerDereference(_In_ PFLT_OBJECT Object)
|
||||||
|
{
|
||||||
|
if (!InterlockedDecrement((PLONG)Object->PointerCount))
|
||||||
|
{
|
||||||
|
// Cleanup
|
||||||
|
FLT_ASSERT(FALSE);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue