47 InsertIrp(IN PIO_CSQ Csq, IN PIRP Irp)
53 PERF_EVENT_VERBOSE(0x3000, (ULONG)Irp);
58 queue = CONTAINING_RECORD(Csq,
QUEUE, IrpQueue);
63 InsertTailList(&queue->
IrpListHead, &Irp->Tail.Overlay.ListEntry);
65 PERF_EVENT_VERBOSE(0x3001, 0);
91 RemoveIrp(IN PIO_CSQ Csq, IN PIRP Irp)
95 UNREFERENCED_PARAMETER(Csq);
97 PERF_EVENT_VERBOSE(0x3010, (ULONG)Irp);
102 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
104 PERF_EVENT_VERBOSE(0x3011, 0);
149 PeekNextIrp(IN PIO_CSQ Csq, IN PIRP Irp, IN PVOID FileObject)
151 PLIST_ENTRY currentListEntry;
160 queue = CONTAINING_RECORD(Csq,
QUEUE, IrpQueue);
176 currentListEntry = Irp->Tail.Overlay.ListEntry.Flink;
186 currentIrp = CONTAINING_RECORD(currentListEntry, IRP, Tail.Overlay.ListEntry);
204 while ((currentListEntry != &queue->
IrpListHead) && !found)
206 PIO_STACK_LOCATION irpStack;
211 irpStack = IoGetCurrentIrpStackLocation(currentIrp);
213 if (irpStack->FileObject == (PFILE_OBJECT) FileObject)
221 currentListEntry = currentListEntry->Flink;
224 currentIrp = CONTAINING_RECORD(currentListEntry, IRP,
225 Tail.Overlay.ListEntry);
269 AcquireLock(IN PIO_CSQ Csq, OUT PKIRQL Irql)
281 queue = CONTAINING_RECORD(Csq,
QUEUE, IrpQueue);
285 DBG_IRQL( <= DISPATCH_LEVEL);
314 ReleaseLock(IN PIO_CSQ Csq, IN KIRQL Irql)
323 queue = CONTAINING_RECORD(Csq,
QUEUE, IrpQueue);
327 DBG_IRQL( == DISPATCH_LEVEL);
356 CompleteCanceledIrp(IN PIO_CSQ Csq, IN PIRP Irp)
367 queue = CONTAINING_RECORD(Csq,
QUEUE, IrpQueue);
399 DBG_IRQL( == PASSIVE_LEVEL);
400 KeInitializeEvent(&Queue->
NotEmptyEvent, SynchronizationEvent, FALSE);
402 #ifdef USE_FAST_START_THREAD
405 DBG_IRQL( == PASSIVE_LEVEL);
406 KeInitializeEvent(&Queue->BackSignalEvent, SynchronizationEvent, FALSE);
408 #endif // #ifdef USE_FAST_START_THREAD
418 CompleteCanceledIrp);
469 NTSTATUS ntStatus = STATUS_SUCCESS;
478 PERF_EVENT_VERBOSE(0x3020, (ULONG)Irp);
484 PERF_EVENT_VERBOSE(0x3021, (ULONG)Irp);
503 PERF_EVENT_VERBOSE(0x3022, (ULONG)Irp);
507 PERF_EVENT_VERBOSE(0x3023, 0);
525 PERF_EVENT_VERBOSE(0x3024, (ULONG)Irp);
530 DBG_IRQL( <= DISPATCH_LEVEL);
531 IoMarkIrpPending(Irp);
536 IoCsqInsertIrp(&Queue->
IrpQueue, Irp, NULL);
538 PERF_EVENT_VERBOSE(0x3025, 0);
545 PERF_EVENT_VERBOSE(0x3026, 0);
551 ntStatus = STATUS_PENDING;
563 FUNC_LEAVE_NTSTATUS(ntStatus);
586 QueueRemoveNextIrp(
PQUEUE Queue)
594 irp = IoCsqRemoveNextIrp(&Queue->
IrpQueue, NULL);
596 PERF_EVENT_VERBOSE(0x3030, (ULONG)irp);
623 ret = InterlockedIncrement(&Queue->
IsStalled);
652 ret = InterlockedDecrement(&Queue->
IsStalled);
778 Irp->IoStatus.Information = Information;
779 Irp->IoStatus.Status = NtStatus;
785 DBG_IRQL( <= DISPATCH_LEVEL);
786 IoCompleteRequest(Irp, IO_NO_INCREMENT);
791 FUNC_LEAVE_NTSTATUS(NtStatus);
822 DBG_IRQL( == PASSIVE_LEVEL);
828 PERF_EVENT_VERBOSE(0x3040, 0);
830 irp = QueueRemoveNextIrp(Queue);
832 PERF_EVENT_VERBOSE(0x3041, (ULONG)irp);
838 PERF_EVENT_VERBOSE(0x3042, (ULONG)irp);
846 PERF_EVENT_VERBOSE(0x3043, (ULONG)irp);
848 #ifdef USE_FAST_START_THREAD
852 DBG_IRQL( <= DISPATCH_LEVEL);
853 KeSetEvent(&Queue->BackSignalEvent, IO_NO_INCREMENT, FALSE);
855 PERF_EVENT_VERBOSE(0x3044, (ULONG)irp);
857 #endif USE_FAST_START_THREAD
864 irp = QueueRemoveNextIrp(Queue);
866 PERF_EVENT_VERBOSE(0x3045, (ULONG)irp);
887 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
902 #ifdef USE_FAST_START_THREAD
904 LARGE_INTEGER timeout;
906 #endif // #ifdef USE_FAST_START_THREAD
912 #ifdef USE_FAST_START_THREAD
917 PERF_EVENT_VERBOSE(0x3050, 0);
919 if (KeGetCurrentIrql() == PASSIVE_LEVEL)
923 DBG_IRQL( <= DISPATCH_LEVEL);
924 KeClearEvent(&Queue->BackSignalEvent);
926 PERF_EVENT_VERBOSE(0x3051, 0);
930 timeout.QuadPart = 1;
935 DBG_IRQL( == PASSIVE_LEVEL);
938 PERF_EVENT_VERBOSE(0x3052, 0);
948 KeWaitForSingleObject(&Queue->BackSignalEvent,
954 PERF_EVENT_VERBOSE(0x3053, 0);
960 PERF_EVENT_VERBOSE(0x3054, 0);
962 DBG_IRQL( <= DISPATCH_LEVEL);
965 PERF_EVENT_VERBOSE(0x3055, 0);
968 #else // #ifdef USE_FAST_START_THREAD
970 DBG_IRQL( <= DISPATCH_LEVEL);
973 #endif // #ifdef USE_FAST_START_THREAD
976 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
1007 irp = IoCsqRemoveNextIrp(&Queue->
IrpQueue, FileObject);
1019 irp = IoCsqRemoveNextIrp(&Queue->
IrpQueue, FileObject);
1024 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
NTSTATUS QueueCompleteIrp(PQUEUE Queue, PIRP Irp, NTSTATUS NtStatus, ULONG_PTR Information)
Complete an IRP which is on a QUEUE.
BOOLEAN QueueShouldCancelCurrentIrp(PQUEUE Queue)
Should the current IRP be cancelled?
KEVENT NotEmptyEvent
signal that the queue is not empty
#define FUNC_LEAVE_BOOLEAN(_xxx)
NTSTATUS(* PCBMDRIVER_STARTIO)(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
VOID QueueInit(PQUEUE Queue, PCBMDRIVER_STARTIO DriverStartIo)
Initialize a QUEUE object.
A QUEUE object A QUEUE object is an object which can be used to queue IRPs for processing. This QUEUE object is optimized for being polled from an own worker thread. Anyway, a concept called FastStart is also implemented, which allows some IRPs to be completed immediately, without being queued, if no IRP is executed yet and the caller has stated that he wants this IRP to be started fast if possible.
VOID QueueUnstall(PQUEUE Queue)
Sets a QUEUE into unstalled state.
#define FUNC_LEAVE_PTR(_xxx, _TYPE)
LIST_ENTRY IrpListHead
the list head for the IRP list
VOID QueueStall(PQUEUE Queue)
Sets a QUEUE into stalled state.
BOOLEAN QueueIsStalled(PQUEUE Queue)
Check if a QUEUE is in stalled state.
KSPIN_LOCK IrpListSpinlock
the spin lock to protect the IRP list
#define PERF_EVENT_COMPLETEIRP(_x_)
NTSTATUS QueueStartPacket(PQUEUE Queue, PIRP Irp, BOOLEAN FastStart, PDEVICE_OBJECT Fdo)
Insert an IRP into a QUEUE object.
PIRP CurrentIrp
Pointer to the IRP which is currently processed.
NTSTATUS QueueCleanup(PQUEUE Queue, PFILE_OBJECT FileObject)
Process an IRP_MJ_CLEANUP on the QUEUE.
PCBMDRIVER_STARTIO DriverStartIo
pointer to the StartIo function to be called
Definitions for the opencbm driver.
LONG IsStalled
counter; if != 0, this queue is stalled, that is, no entries are dequeued.
NTSTATUS QueuePoll(PQUEUE Queue, PDEVICE_OBJECT Fdo)
Poll the QUEUE.
#define PERF_EVENT_CANCELIRP(_x_)
IO_CSQ IrpQueue
the structure for the cancel-safe queue
LONG IsDropping
counter; if != 0, this queue is dropping, that is, no new entries are queued into the queue; instead...
BOOLEAN QueueIsDropping(PQUEUE Queue)
Check if a QUEUE is in DROPPING state.
NTSTATUS DroppingReturnStatus
The NTSTATUS return code with which the IRP are completed if we are dropping IRPs.
NTSTATUS QueueSignal(PQUEUE Queue)
Signal to the QUEUE need for processing.