diff --git a/xtoskrnl/includes/ke/pushlock.hh b/xtoskrnl/includes/ke/pushlock.hh index 0c23f49..4a6c536 100644 --- a/xtoskrnl/includes/ke/pushlock.hh +++ b/xtoskrnl/includes/ke/pushlock.hh @@ -22,6 +22,7 @@ namespace KE STATIC XTFASTCALL VOID AcquireSharedPushLock(PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID AcquireWaitExclusivePushLock(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID AcquireWaitSharedPushLock(IN OUT PKPUSH_LOCK PushLock); + STATIC XTFASTCALL BOOLEAN ConvertSharedPushLockToExclusive(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID InitializePushLock(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID ReleaseExclusivePushLock(IN PKPUSH_LOCK PushLock); STATIC XTFASTCALL VOID ReleasePushLock(IN PKPUSH_LOCK PushLock); diff --git a/xtoskrnl/ke/pushlock.cc b/xtoskrnl/ke/pushlock.cc index e6fe1d5..6540fab 100644 --- a/xtoskrnl/ke/pushlock.cc +++ b/xtoskrnl/ke/pushlock.cc @@ -299,6 +299,31 @@ KE::PushLock::AcquireWaitSharedPushLock(IN PKPUSH_LOCK PushLock) } } +/** + * Attempts to convert a push lock from shared to exclusive access. + * + * @param PushLock + * Supplies a pointer to the push lock structure. + * + * @return This routine returns TRUE if the lock was successfully converted to exclusive mode, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTFASTCALL +BOOLEAN +KE::PushLock::ConvertSharedPushLockToExclusive(IN PKPUSH_LOCK PushLock) +{ + PVOID OldValue; + + /* Swap the push lock state */ + OldValue = RTL::Atomic::CompareExchangePointer(&PushLock->Ptr, + (PVOID)KPUSHLOCK_INCREMENT_SHARED, + (PVOID)KPUSHLOCK_LOCK); + + /* Return conversion result */ + return (OldValue == (PVOID)KPUSHLOCK_INCREMENT_SHARED); +} + /** * Initializes a push lock. *