mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
irp cancelation boiler plate, for irp queues you manage yourself
svn path=/trunk/; revision=13852
This commit is contained in:
parent
ca4d8c0923
commit
4369eecce7
1 changed files with 102 additions and 0 deletions
102
reactos/doc/irp cancel boilerplate.c
Normal file
102
reactos/doc/irp cancel boilerplate.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
|
||||
|
||||
/*
|
||||
Boiler plate for irp cancelation, for irp queues you manage yourself
|
||||
-Gunnar
|
||||
*/
|
||||
|
||||
|
||||
|
||||
CancelRoutine(
|
||||
DEV_OBJ Dev,
|
||||
Irp
|
||||
)
|
||||
{
|
||||
//don't need this since we have our own sync. protecting irp cancellation
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
|
||||
theLock = Irp->Tail.Overlay.DriverContext[3];
|
||||
|
||||
Lock(theLock);
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
Unlock(theLock);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
QUEUE_BOLIERPLATE
|
||||
{
|
||||
Lock(theLock);
|
||||
|
||||
Irp->Tail.Overlay.DriverContext[3] = &theLock;
|
||||
|
||||
IoSetCancelRoutine(Irp, CancelRoutine);
|
||||
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
// IRP has already been cancelled (before we got to queue it),
|
||||
// but we got to remove the cancel routine before the canceler could,
|
||||
// so complete irp ourself
|
||||
|
||||
Unlock(theLock);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//else were ok
|
||||
|
||||
|
||||
Irp->IoStatus.Status = STATUS_PENDING;
|
||||
IoMarkIrpPending(Irp);
|
||||
|
||||
InsertTailList(Queue);
|
||||
|
||||
Unlock(theLock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
DEQUEUE_BOILERPLATE
|
||||
{
|
||||
Lock(theLock);
|
||||
|
||||
Irp = RemoveHeadList(Queue);
|
||||
|
||||
if (!IoSetCancelRoutine(Irp, NULL))
|
||||
{
|
||||
/*
|
||||
Cancel routine WILL be called after we release the spinlock. It will try to remove
|
||||
the irp from the list and cancel/complete this irp. Since we allready removed it,
|
||||
make its ListEntry point to itself.
|
||||
*/
|
||||
|
||||
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Cancel routine will NOT be called, canceled or not.
|
||||
The Irp might have been canceled (Irp->Cancel flag set) but we don't care,
|
||||
since we are to complete this Irp now anyways.
|
||||
*/
|
||||
|
||||
Unlock(theLock);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue