mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:55:39 +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…
Add table
Add a link
Reference in a new issue