static
__inline
-VOID
-IopLockFileObject(IN PFILE_OBJECT FileObject)
+NTSTATUS
+IopLockFileObject(
+ _In_ PFILE_OBJECT FileObject,
+ _In_ KPROCESSOR_MODE WaitMode)
{
+ BOOLEAN LockFailed;
+
/* Lock the FO and check for contention */
- InterlockedIncrement((PLONG)&FileObject->Waiters);
- while (InterlockedCompareExchange((PLONG)&FileObject->Busy, TRUE, FALSE) != FALSE)
+ if (InterlockedExchange((PLONG)&FileObject->Busy, TRUE) == FALSE)
+ {
+ ObReferenceObject(FileObject);
+ return STATUS_SUCCESS;
+ }
+ else
{
- /* FIXME - pause for a little while? */
+ return IopAcquireFileObjectLock(FileObject,
+ WaitMode,
+ BooleanFlagOn(FileObject->Flags, FO_ALERTABLE_IO),
+ &LockFailed);
}
- InterlockedDecrement((PLONG)&FileObject->Waiters);
}
static
IopUnlockFileObject(IN PFILE_OBJECT FileObject)
{
/* Unlock the FO and wake any waiters up */
- InterlockedExchange((PLONG)&FileObject->Busy, FALSE);
- if (FileObject->Waiters) KeSetEvent(&FileObject->Lock, 0, FALSE);
+ NT_VERIFY(InterlockedExchange((PLONG)&FileObject->Busy, FALSE) == TRUE);
+ if (FileObject->Waiters)
+ {
+ KeSetEvent(&FileObject->Lock, IO_NO_INCREMENT, FALSE);
+ }
+ ObDereferenceObject(FileObject);
}
FORCEINLINE