Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

IRP Cancellation - Must we ALWAYS call IoReleaseCancelSpinLock(Irp->CancelIrql); ???

109 views
Skip to first unread message

Nate Bushman

unread,
Sep 3, 2002, 4:59:35 PM9/3/02
to
I manage my own IRP queues (I don't use the I/O-manager-supplied device
queue in the device object) and want to properly cancel IRPs in my queues.
The documentation for IoSetCancelRoutine() indicates that if I manage my
queues I don't need to acquire/release the cancel spinlock within my cancel
routine. However, it then says that Driver Cancel routines are called with
the cancel spinlock held... does this mean that even though I manage my own
queue I still need to release the cancel spinlock as in the code below?

VOID
CancelRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
// Release the system-wide cancel spinlock ASAP
IoReleaseCancelSpinLock(Irp->CancelIrql);

// Dequeue the IRP from my CUSTOM queue (if it's still in the queue)
// ...

// Cancel the IRP
if (IrpWasInQueue)
{
IoSetCancelRoutine(Irp, NULL);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
}

By the way, I think there may be a typo in the docs for
IoSetCancelRoutine(), which mention the a IoSetCancelSpinLock() routine that
doesn't seem to exist.

Neill Clift [MS]

unread,
Sep 3, 2002, 6:49:50 PM9/3/02
to
Yes you always have to release this lock in your cancel routine as its
always acquired by the cancel code in the i/o manager before it calls you.

As an aside you don't need to remove your cancel routine below in
cancelation as that should be done for you by the i/o manager before it
calls your routine. In fact this is a basic mechanism we use for
cancelation. We do atomic swaps on the cancel routine field of the IRP to
get the routine to call.
Neill.

--
This posting is provided "AS IS" with no warranties, and confers no rights.

"Nate Bushman" <nate.bushman@NO_SPAAAMpowerquest.com> wrote in message
news:uKw0gz4UCHA.2716@tkmsftngp12...

Nate Bushman

unread,
Sep 4, 2002, 11:06:14 AM9/4/02
to
Just to make sure that I'm clear on this, in your aside did you mean that
it's not necessary to have the statement IoSetCancelRoutine(Irp, NULL); in
the Cancel Routine?

Also, what is the proper behavior of the Cancel Routine if it doesn't find
the IRP in a queue (ie the IRP has been dequeued and may be in the process
of being dispatched). Should the Cancel Routine do nothing in this case,
and simply let the dispatching code complete the IRP?


"Neill Clift [MS]" <nei...@microsoft.com> wrote in message
news:3d753c8f$1...@news.microsoft.com...

Walter Oney

unread,
Sep 4, 2002, 12:42:32 PM9/4/02
to
Nate Bushman wrote:
> Just to make sure that I'm clear on this, in your aside did you mean that
> it's not necessary to have the statement IoSetCancelRoutine(Irp, NULL); in
> the Cancel Routine?

Yes, that's what he meant. IoCancelIrp has already done this.

> Also, what is the proper behavior of the Cancel Routine if it doesn't find
> the IRP in a queue (ie the IRP has been dequeued and may be in the process
> of being dispatched). Should the Cancel Routine do nothing in this case,
> and simply let the dispatching code complete the IRP?

It's best to arrange matters so that the cancel routine always removes
the IRP from some queue and completes it. The DEVQUEUE code in my WDM
book (as modified by a long-ago service pack) appears to be bulletproof,
and I know that much of the same logic was incorporated (coincidentally
or not--and it doesn't matter) into the cancel-safe queue that's in the
XP DDK.

--
Walter Oney
Consulting and Training
http://www.oneysoft.com

Nate Bushman

unread,
Sep 5, 2002, 1:36:12 PM9/5/02
to
Well, for an NT4 driver (which I'm working on), I don't have IoCsqXxx calls
and probably can't use your DEVQUEUE code (?). So the question still
stands, if the Cancel Routine gets called, and the IRP that the routine is
called for was just barely dequeued and is in the process of being
dispatched, what should the Cancel Routine do? Just return (do nothing)?

Also, does this mean that in order to have a cancel safe queue, my code that
accesses the queue needs to use the system-wide cancel spinlock for
synchronization (acquiring/releasing the cancel spinlock when accessing the
queue), rather than just some spinlock that I've created?

"Walter Oney" <walt...@oneysoft.com> wrote in message
news:3D7637F8...@oneysoft.com...

Nate Bushman

unread,
Sep 5, 2002, 3:59:04 PM9/5/02
to
Walter, nevermind. I reread pgs 253-254 in your book and it finally dawned
on me why IoSetCancelRoutine() performs the atomic exchange of cancel
routine addresses. I Now I understand how, in my dispatch routine, to see
if my cancel routine has been called for the IRP I'm about to dispatch, so
that I can go ahead and queue that IRP and release lock and let the cancel
routine take care of it. Thanks for the clear explaination AND sample code
in the book - VERY HELPFUL!

Nate

"Nate Bushman" <nate.bushman@NO_SPAAAMpowerquest.com> wrote in message

news:uN5qMLQVCHA.3556@tkmsftngp08...

Walter Oney

unread,
Sep 6, 2002, 6:13:37 AM9/6/02
to
Nate Bushman wrote:
> Walter, nevermind. I reread pgs 253-254 in your book and it finally dawned
> on me why IoSetCancelRoutine() performs the atomic exchange of cancel
> routine addresses. I Now I understand how, in my dispatch routine, to see
> if my cancel routine has been called for the IRP I'm about to dispatch, so
> that I can go ahead and queue that IRP and release lock and let the cancel
> routine take care of it. Thanks for the clear explaination AND sample code
> in the book - VERY HELPFUL!

You're welcome, and thanks for the pat on the back. With the 9/11
anniversary coming up, I've been feeling pretty low...

0 new messages