mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 05:00:27 +00:00
- Implement KiAcquireDeviceQueueLock/KiReleaseDeviceQueueLock for locking KDEVICE_QUEUEs, since they can be used from Threaded DPCs which don't execute at DISPATCH_LEVEL, so the lock needs to be acquired differently.
- Add ASSERT_DEVICE_QUEUE and ASSERTify + reformat kqueue.c. - Implement KeRemoveByKeyDeviceQueueIfBusy. - Cleanup exception.c - Remove dangerous/broken KeGetCurrentIrql() define. svn path=/trunk/; revision=24087
This commit is contained in:
parent
c0cda24302
commit
d99f96a295
5 changed files with 200 additions and 130 deletions
|
@ -1093,6 +1093,9 @@ typedef struct _KLOCK_QUEUE_HANDLE {
|
|||
((Object)->Type == DpcObject) || \
|
||||
((Object)->Type == ThreadedDpcObject))
|
||||
|
||||
#define ASSERT_DEVICE_QUEUE(Object) \
|
||||
ASSERT((Object)->Type == DeviceQueueObject)
|
||||
|
||||
typedef struct _KDPC
|
||||
{
|
||||
UCHAR Type;
|
||||
|
|
|
@ -124,7 +124,6 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
|
|||
#define LOCK "lock ; "
|
||||
#else
|
||||
#define LOCK ""
|
||||
#define KeGetCurrentIrql() (((PKPCR)KPCR_BASE)->Irql)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
|
|
@ -696,6 +696,44 @@ KiReleaseProcessLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle)
|
|||
KeReleaseInStackQueuedSpinLockFromDpcLevel(Handle);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KiAcquireDeviceQueueLock(IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN PKLOCK_QUEUE_HANDLE DeviceLock)
|
||||
{
|
||||
/* Check if we were called from a threaded DPC */
|
||||
if (KeGetCurrentPrcb()->DpcThreadActive)
|
||||
{
|
||||
/* Lock the Queue, we're not at DPC level */
|
||||
KeAcquireInStackQueuedSpinLock(&DeviceQueue->Lock, DeviceLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We must be at DPC level, acquire the lock safely */
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
KeAcquireInStackQueuedSpinLockAtDpcLevel(&DeviceQueue->Lock,
|
||||
DeviceLock);
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KiReleaseDeviceQueueLock(IN PKLOCK_QUEUE_HANDLE DeviceLock)
|
||||
{
|
||||
/* Check if we were called from a threaded DPC */
|
||||
if (KeGetCurrentPrcb()->DpcThreadActive)
|
||||
{
|
||||
/* Unlock the Queue, we're not at DPC level */
|
||||
KeReleaseInStackQueuedSpinLock(DeviceLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We must be at DPC level, release the lock safely */
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
KeReleaseInStackQueuedSpinLockFromDpcLevel(DeviceLock);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This routine queues a thread that is ready on the PRCB's ready lists.
|
||||
// If this thread cannot currently run on this CPU, then the thread is
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ke/exception.c
|
||||
* PURPOSE: Platform independent exception handling
|
||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
|
@ -46,11 +46,7 @@ KiContinue(IN PCONTEXT Context,
|
|||
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||
|
||||
/* Raise to APC_LEVEL, only if needed */
|
||||
if (KeGetCurrentIrql() < APC_LEVEL)
|
||||
{
|
||||
/* Raise to APC_LEVEL */
|
||||
KeRaiseIrql(APC_LEVEL, &OldIrql);
|
||||
}
|
||||
if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
|
||||
|
||||
/* Set up SEH to validate the context */
|
||||
_SEH_TRY
|
||||
|
@ -75,6 +71,7 @@ KiContinue(IN PCONTEXT Context,
|
|||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
/* Save the exception code */
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
@ -88,18 +85,17 @@ KiContinue(IN PCONTEXT Context,
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KiRaiseException(PEXCEPTION_RECORD ExceptionRecord,
|
||||
PCONTEXT Context,
|
||||
PKEXCEPTION_FRAME ExceptionFrame,
|
||||
PKTRAP_FRAME TrapFrame,
|
||||
BOOLEAN SearchFrames)
|
||||
KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT Context,
|
||||
IN PKEXCEPTION_FRAME ExceptionFrame,
|
||||
IN PKTRAP_FRAME TrapFrame,
|
||||
IN BOOLEAN SearchFrames)
|
||||
{
|
||||
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||
CONTEXT LocalContext;
|
||||
EXCEPTION_RECORD LocalExceptionRecord;
|
||||
ULONG ParameterCount, Size;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
DPRINT1("KiRaiseException\n");
|
||||
|
||||
/* Set up SEH */
|
||||
_SEH_TRY
|
||||
|
@ -143,10 +139,12 @@ KiRaiseException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
/* Get the exception code */
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
/* Make sure we didn't crash in SEH */
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Convert the context record */
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PURPOSE: ReactOS kernel
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ke/kqueue.c
|
||||
* PURPOSE: Implement device queues
|
||||
*
|
||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Several optimizations and implement
|
||||
* usage of Inserted flag + reformat and
|
||||
* add debug output.
|
||||
* David Welch (welch@mcmail.com)
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
|
@ -20,16 +16,11 @@
|
|||
|
||||
/*
|
||||
* @implemented
|
||||
*
|
||||
* FUNCTION: Intializes a device queue
|
||||
* ARGUMENTS:
|
||||
* DeviceQueue = Device queue to initialize
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
|
||||
{
|
||||
|
||||
/* Initialize the Header */
|
||||
DeviceQueue->Type = DeviceQueueObject;
|
||||
DeviceQueue->Size = sizeof(KDEVICE_QUEUE);
|
||||
|
@ -44,48 +35,41 @@ KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
|
|||
|
||||
/*
|
||||
* @implemented
|
||||
*
|
||||
* FUNCTION: Inserts an entry in a device queue
|
||||
* ARGUMENTS:
|
||||
* DeviceQueue = Queue to insert the entry in
|
||||
* DeviceQueueEntry = Entry to insert
|
||||
* RETURNS: False is the device queue wasn't busy
|
||||
* True otherwise
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
|
||||
{
|
||||
KLOCK_QUEUE_HANDLE DeviceLock;
|
||||
BOOLEAN Inserted;
|
||||
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
||||
|
||||
DPRINT("KeInsertDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
|
||||
/* Lock the Queue */
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
|
||||
|
||||
if (!DeviceQueue->Busy) {
|
||||
/* Lock the queue */
|
||||
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
||||
|
||||
/* Check if it's not busy */
|
||||
if (!DeviceQueue->Busy)
|
||||
{
|
||||
/* Set it as busy */
|
||||
Inserted = FALSE;
|
||||
DeviceQueue->Busy = TRUE;
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Insert it into the list */
|
||||
Inserted = TRUE;
|
||||
InsertTailList(&DeviceQueue->DeviceListHead,
|
||||
&DeviceQueueEntry->DeviceListEntry);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Sert the Insert state into the entry */
|
||||
DeviceQueueEntry->Inserted = Inserted;
|
||||
|
||||
/* Release lock and return */
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
|
||||
/* Release the lock */
|
||||
KiReleaseDeviceQueueLock(&DeviceLock);
|
||||
|
||||
/* Return the state */
|
||||
return Inserted;
|
||||
}
|
||||
|
||||
|
@ -93,29 +77,30 @@ KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
|||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
|
||||
IN ULONG SortKey)
|
||||
{
|
||||
KLOCK_QUEUE_HANDLE DeviceLock;
|
||||
BOOLEAN Inserted;
|
||||
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
||||
|
||||
DPRINT("KeInsertByKeyDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
|
||||
/* Acquire the Lock */
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
|
||||
/* Lock the queue */
|
||||
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
||||
|
||||
/* Set the Sort Key */
|
||||
DeviceQueueEntry->SortKey=SortKey;
|
||||
DeviceQueueEntry->SortKey = SortKey;
|
||||
|
||||
if (!DeviceQueue->Busy) {
|
||||
|
||||
DeviceQueue->Busy=TRUE;
|
||||
/* Check if it's not busy */
|
||||
if (!DeviceQueue->Busy)
|
||||
{
|
||||
/* Set it as busy */
|
||||
Inserted = FALSE;
|
||||
|
||||
} else {
|
||||
|
||||
DeviceQueue->Busy = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Insert new entry after the last entry with SortKey less or equal to passed-in SortKey */
|
||||
InsertAscendingListFIFO(&DeviceQueue->DeviceListHead,
|
||||
DeviceQueueEntry,
|
||||
|
@ -125,43 +110,38 @@ KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
|||
Inserted = TRUE;
|
||||
}
|
||||
|
||||
/* Reset the Inserted State */
|
||||
DeviceQueueEntry->Inserted = Inserted;
|
||||
/* Release the lock */
|
||||
KiReleaseDeviceQueueLock(&DeviceLock);
|
||||
|
||||
/* Release Lock and Return */
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
|
||||
/* Return the state */
|
||||
return Inserted;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*
|
||||
* FUNCTION: Removes an entry from a device queue
|
||||
* ARGUMENTS:
|
||||
* DeviceQueue = Queue to remove the entry
|
||||
* RETURNS: The removed entry
|
||||
*/
|
||||
PKDEVICE_QUEUE_ENTRY
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
PKDEVICE_QUEUE_ENTRY ReturnEntry;
|
||||
KLOCK_QUEUE_HANDLE DeviceLock;
|
||||
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
||||
|
||||
DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
|
||||
/* Acquire the Lock */
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
|
||||
/* Lock the queue */
|
||||
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
||||
ASSERT(DeviceQueue->Busy);
|
||||
|
||||
/* An attempt to remove an entry from an empty (and busy) queue sets the queue idle */
|
||||
if (IsListEmpty(&DeviceQueue->DeviceListHead)) {
|
||||
/* Check if this is an empty queue */
|
||||
if (IsListEmpty(&DeviceQueue->DeviceListHead))
|
||||
{
|
||||
/* Set it to idle and return nothing*/
|
||||
DeviceQueue->Busy = FALSE;
|
||||
ReturnEntry = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove the Entry from the List */
|
||||
ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
|
||||
ReturnEntry = CONTAINING_RECORD(ListEntry,
|
||||
|
@ -172,8 +152,10 @@ KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
|
|||
ReturnEntry->Inserted = FALSE;
|
||||
}
|
||||
|
||||
/* Release lock and Return */
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
|
||||
/* Release the lock */
|
||||
KiReleaseDeviceQueueLock(&DeviceLock);
|
||||
|
||||
/* Return the entry */
|
||||
return ReturnEntry;
|
||||
}
|
||||
|
||||
|
@ -181,33 +163,34 @@ KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
|
|||
* @implemented
|
||||
*/
|
||||
PKDEVICE_QUEUE_ENTRY
|
||||
STDCALL
|
||||
KeRemoveByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN ULONG SortKey)
|
||||
NTAPI
|
||||
KeRemoveByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN ULONG SortKey)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
PKDEVICE_QUEUE_ENTRY ReturnEntry;
|
||||
KLOCK_QUEUE_HANDLE DeviceLock;
|
||||
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
||||
|
||||
DPRINT("KeRemoveByKeyDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
|
||||
/* Acquire the Lock */
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
|
||||
/* Lock the queue */
|
||||
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
||||
ASSERT(DeviceQueue->Busy);
|
||||
|
||||
/* An attempt to remove an entry from an empty (and busy) queue sets the queue idle */
|
||||
if (IsListEmpty(&DeviceQueue->DeviceListHead)) {
|
||||
|
||||
/* Check if this is an empty queue */
|
||||
if (IsListEmpty(&DeviceQueue->DeviceListHead))
|
||||
{
|
||||
/* Set it to idle and return nothing*/
|
||||
DeviceQueue->Busy = FALSE;
|
||||
ReturnEntry = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Find entry with SortKey greater than or equal to the passed-in SortKey */
|
||||
LIST_FOR_EACH(ReturnEntry, &DeviceQueue->DeviceListHead, KDEVICE_QUEUE_ENTRY, DeviceListEntry)
|
||||
{
|
||||
/* Check if keys match */
|
||||
if (ReturnEntry->SortKey >= SortKey) {
|
||||
if (ReturnEntry->SortKey >= SortKey)
|
||||
{
|
||||
/* We found it, so just remove it */
|
||||
RemoveEntryList(&ReturnEntry->DeviceListEntry);
|
||||
break;
|
||||
|
@ -215,61 +198,110 @@ KeRemoveByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue,
|
|||
}
|
||||
|
||||
/* Check if we found something */
|
||||
if (!ReturnEntry) {
|
||||
|
||||
if (!ReturnEntry)
|
||||
{
|
||||
/* Not found, return the first entry */
|
||||
ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
|
||||
ReturnEntry = CONTAINING_RECORD(ListEntry,
|
||||
KDEVICE_QUEUE_ENTRY,
|
||||
DeviceListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set it as non-inserted */
|
||||
ReturnEntry->Inserted = FALSE;
|
||||
}
|
||||
|
||||
/* Release lock and Return */
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
|
||||
return ReturnEntry;
|
||||
}
|
||||
/* Release the lock */
|
||||
KiReleaseDeviceQueueLock(&DeviceLock);
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
PKDEVICE_QUEUE_ENTRY
|
||||
STDCALL
|
||||
KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN ULONG SortKey)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
/* Return the entry */
|
||||
return ReturnEntry;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN STDCALL
|
||||
PKDEVICE_QUEUE_ENTRY
|
||||
NTAPI
|
||||
KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN ULONG SortKey)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
PKDEVICE_QUEUE_ENTRY ReturnEntry;
|
||||
KLOCK_QUEUE_HANDLE DeviceLock;
|
||||
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
||||
|
||||
/* Lock the queue */
|
||||
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
||||
|
||||
/* Check if this is an empty or idle queue */
|
||||
if (!(DeviceQueue->Busy) || (IsListEmpty(&DeviceQueue->DeviceListHead)))
|
||||
{
|
||||
/* Set it to idle and return nothing*/
|
||||
DeviceQueue->Busy = FALSE;
|
||||
ReturnEntry = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Find entry with SortKey greater than or equal to the passed-in SortKey */
|
||||
LIST_FOR_EACH(ReturnEntry, &DeviceQueue->DeviceListHead, KDEVICE_QUEUE_ENTRY, DeviceListEntry)
|
||||
{
|
||||
/* Check if keys match */
|
||||
if (ReturnEntry->SortKey >= SortKey)
|
||||
{
|
||||
/* We found it, so just remove it */
|
||||
RemoveEntryList(&ReturnEntry->DeviceListEntry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we found something */
|
||||
if (!ReturnEntry)
|
||||
{
|
||||
/* Not found, return the first entry */
|
||||
ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
|
||||
ReturnEntry = CONTAINING_RECORD(ListEntry,
|
||||
KDEVICE_QUEUE_ENTRY,
|
||||
DeviceListEntry);
|
||||
}
|
||||
|
||||
/* Set it as non-inserted */
|
||||
ReturnEntry->Inserted = FALSE;
|
||||
}
|
||||
|
||||
/* Release the lock */
|
||||
KiReleaseDeviceQueueLock(&DeviceLock);
|
||||
|
||||
/* Return the entry */
|
||||
return ReturnEntry;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KeRemoveEntryDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
||||
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
BOOLEAN OldState;
|
||||
KLOCK_QUEUE_HANDLE DeviceLock;
|
||||
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
||||
|
||||
DPRINT("KeRemoveEntryDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
|
||||
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
|
||||
|
||||
/* Acquire the Lock */
|
||||
KeAcquireSpinLock(&DeviceQueue->Lock, &OldIrql);
|
||||
|
||||
/* Check/Set Old State */
|
||||
if ((OldState = DeviceQueueEntry->Inserted)) {
|
||||
/* Lock the queue */
|
||||
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
||||
ASSERT(DeviceQueue->Busy);
|
||||
|
||||
/* Check the insertion state */
|
||||
OldState = DeviceQueueEntry->Inserted;
|
||||
if (OldState)
|
||||
{
|
||||
/* Remove it */
|
||||
DeviceQueueEntry->Inserted = FALSE;
|
||||
RemoveEntryList(&DeviceQueueEntry->DeviceListEntry);
|
||||
}
|
||||
|
||||
/* Unlock and return old state */
|
||||
KeReleaseSpinLock(&DeviceQueue->Lock, OldIrql);
|
||||
KiReleaseDeviceQueueLock(&DeviceLock);
|
||||
return OldState;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue