WDF queueing

Coming from WDM, I am finding myself unsure of what exactly is done for my by WDF when it comes to queues.

I have requests that come in through an IOCTL. I have setup a default queue, and if I understand this correctly, when my IOCTL dispatch routine receives a Request, it came from that default queue. I am assuming it was taken off that queue before my dispatch routine got it. Is that correct?

I am trying to implement Irp cancellation. As part of that, I was going to make a queue to keep track of requests that have come in through my IOCTL dispatch routine that are still being worked on by hardware. I will have a deadman timer to cleanup requests in this queue that never got finished by misbehaving hardware. But WdfRequestForwardToIoQueue requires the Request to be uncancellable. Why is this? If I were to put them on this 2nd queue, I would have to make them uncancellable, but these are the very ones that are pending and might get a cancel. I think I must not be understanding something here.

Thanks,
Diane

KMDF will automatically handle cancellation for any request pending in a queue, so you don’t need to have a cancellation routine registered when you forward it to the queue.

If you still need a notification when the request in the queue is cancelled you can register an EvtIoCanceledOnQueue callback on the holding queue when you create it.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@earthlink.net
Sent: Thursday, October 23, 2008 10:48 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WDF queueing

Coming from WDM, I am finding myself unsure of what exactly is done for my by WDF when it comes to queues.

I have requests that come in through an IOCTL. I have setup a default queue, and if I understand this correctly, when my IOCTL dispatch routine receives a Request, it came from that default queue. I am assuming it was taken off that queue before my dispatch routine got it. Is that correct?

I am trying to implement Irp cancellation. As part of that, I was going to make a queue to keep track of requests that have come in through my IOCTL dispatch routine that are still being worked on by hardware. I will have a deadman timer to cleanup requests in this queue that never got finished by misbehaving hardware. But WdfRequestForwardToIoQueue requires the Request to be uncancellable. Why is this? If I were to put them on this 2nd queue, I would have to make them uncancellable, but these are the very ones that are pending and might get a cancel. I think I must not be understanding something here.

Thanks,
Diane


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

What I believe you are missing is that WDF will handle the cancellation for you when the request is in the new queue (and you can provide a callback for additional handling you may need when it is canceled while on the queue).

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@earthlink.net
Sent: Thursday, October 23, 2008 10:48 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WDF queueing

Coming from WDM, I am finding myself unsure of what exactly is done for my by WDF when it comes to queues.

I have requests that come in through an IOCTL. I have setup a default queue, and if I understand this correctly, when my IOCTL dispatch routine receives a Request, it came from that default queue. I am assuming it was taken off that queue before my dispatch routine got it. Is that correct?

I am trying to implement Irp cancellation. As part of that, I was going to make a queue to keep track of requests that have come in through my IOCTL dispatch routine that are still being worked on by hardware. I will have a deadman timer to cleanup requests in this queue that never got finished by misbehaving hardware. But WdfRequestForwardToIoQueue requires the Request to be uncancellable. Why is this? If I were to put them on this 2nd queue, I would have to make them uncancellable, but these are the very ones that are pending and might get a cancel. I think I must not be understanding something here.

Thanks,
Diane

There are actually multiple cancelation states here

  1. if the request is not presented to your driver and it is canceled, kmdf takes care of it for you
  2. the driver can mark an actively presented request as cancelable. You then own the cancelable state of the request
  3. the driver can fwd a request from one queue to another, but only in a non cancelable state. This is b/c the cancel routine logic is centered around the queue the request is currently active on

So, in your case you have 2 options, both involve a 2ndary queue

  1. create a manual queue and fwd your requests to this queue. Requests in a manual queue are automatically cancelable until you pop it out of the queue. As peter mentioned, you can register a EvtIoCanceledOnQueue on the queue and you can be notified of the request being canceled before you pop it

  2. create a parallel or sequential queue (depending on if your hw can operate on N or just 1 requests at a time). In this queues IOCTL presentation routine you set a cancel routine on your own and deal with cancelation logic

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Peter Wieland
Sent: Thursday, October 23, 2008 10:52 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] WDF queueing

KMDF will automatically handle cancellation for any request pending in a queue, so you don’t need to have a cancellation routine registered when you forward it to the queue.

If you still need a notification when the request in the queue is cancelled you can register an EvtIoCanceledOnQueue callback on the holding queue when you create it.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@earthlink.net
Sent: Thursday, October 23, 2008 10:48 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WDF queueing

Coming from WDM, I am finding myself unsure of what exactly is done for my by WDF when it comes to queues.

I have requests that come in through an IOCTL. I have setup a default queue, and if I understand this correctly, when my IOCTL dispatch routine receives a Request, it came from that default queue. I am assuming it was taken off that queue before my dispatch routine got it. Is that correct?

I am trying to implement Irp cancellation. As part of that, I was going to make a queue to keep track of requests that have come in through my IOCTL dispatch routine that are still being worked on by hardware. I will have a deadman timer to cleanup requests in this queue that never got finished by misbehaving hardware. But WdfRequestForwardToIoQueue requires the Request to be uncancellable. Why is this? If I were to put them on this 2nd queue, I would have to make them uncancellable, but these are the very ones that are pending and might get a cancel. I think I must not be understanding something here.

Thanks,
Diane


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Okay, that makes more sense. Thanks for the quick response.

Diane

wrote in message news:xxxxx@ntdev…
> Coming from WDM, I am finding myself unsure of what exactly is done
> for my by WDF when it comes to queues.
>
> I have requests that come in through an IOCTL. I have setup a
> default queue, and if I understand this correctly, when my IOCTL
> dispatch routine receives a Request, it came from that default queue.
> I am assuming it was taken off that queue before my dispatch routine
> got it. Is that correct?
>
> I am trying to implement Irp cancellation. As part of that, I was
> going to make a queue to keep track of requests that have come in
> through my IOCTL dispatch routine that are still being worked on by
> hardware. I will have a deadman timer to cleanup requests in this
> queue that never got finished by misbehaving hardware. But
> WdfRequestForwardToIoQueue requires the Request to be uncancellable.
> Why is this? If I were to put them on this 2nd queue, I would have
> to make them uncancellable, but these are the very ones that are
> pending and might get a cancel. I think I must not be understanding
> something here.

Diane,

Peter, Bob, and Doron all gave you excellent advice. Since I’ve
wrestled with a lot of the same things, I’ll offer up what I’ve
learned. First, if you’ve set up a default queue, but you aren’t
explicitly removing your WDFREQUESTs from it, that would suggest that
you configured it as automatic, either parallel or serial. Actually, I
don’t think you can configure the default queue as manual, because I’m
not sure how you would get notified there is something in it to do.

In any case, you have a callback that is either passed a WDFREQUEST or
pulls a WDFREQUEST off of your WDFQUEUE, and in either case, at that
point, the WDREQUEST is in a not cancellable state. It will only get
in a cancellable state if you call WdfRequestMarkCancelable(). Since
you are already setting up a WDFQUEUE to hold the IOs that are in
flight on the hardware, you don’t need to do that, since the holding
queue will handle cancellation. Just preprocess your IO, start it on
your hardware, and forward it to your holding queue.

I’m guessing that if you have the timer timeout or the IO cancelled,
you need to do approximately the same things to the hardware to clear
the pending IO from it. You can register an EvtIoCanceledOnQueue
callback on your holding queue, as Peter mentioned, so that you can
tickle the hardware to remove a cancelled IO (and clean up any of your
own state).

Here’s where it gets a bit murky in my understanding. I have an old
post on this forum from Doron that said that it’s permissible to simply
complete a WDFREQUEST while it’s on a WDFQUEUE. Doron, is that right?
Can Diane call WdfRequestComplete (or one of it’s siblings) without
removing the WDFREQUEST from the WDFQUEUE it’s living on when she
determines that her hardware is done with it?

Hope this helps,
Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

It can be completed as long as it has not been marked cancelable by the driver. If the request is on a manual queue, it must retrieved before completion.

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: Philip D. Barila
Sent: Thursday, October 23, 2008 11:34 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] WDF queueing

wrote in message news:xxxxx@ntdev…
> Coming from WDM, I am finding myself unsure of what exactly is done
> for my by WDF when it comes to queues.
>
> I have requests that come in through an IOCTL. I have setup a
> default queue, and if I understand this correctly, when my IOCTL
> dispatch routine receives a Request, it came from that default queue.
> I am assuming it was taken off that queue before my dispatch routine
> got it. Is that correct?
>
> I am trying to implement Irp cancellation. As part of that, I was
> going to make a queue to keep track of requests that have come in
> through my IOCTL dispatch routine that are still being worked on by
> hardware. I will have a deadman timer to cleanup requests in this
> queue that never got finished by misbehaving hardware. But
> WdfRequestForwardToIoQueue requires the Request to be uncancellable.
> Why is this? If I were to put them on this 2nd queue, I would have
> to make them uncancellable, but these are the very ones that are
> pending and might get a cancel. I think I must not be understanding
> something here.

Diane,

Peter, Bob, and Doron all gave you excellent advice. Since I’ve
wrestled with a lot of the same things, I’ll offer up what I’ve
learned. First, if you’ve set up a default queue, but you aren’t
explicitly removing your WDFREQUESTs from it, that would suggest that
you configured it as automatic, either parallel or serial. Actually, I
don’t think you can configure the default queue as manual, because I’m
not sure how you would get notified there is something in it to do.

In any case, you have a callback that is either passed a WDFREQUEST or
pulls a WDFREQUEST off of your WDFQUEUE, and in either case, at that
point, the WDREQUEST is in a not cancellable state. It will only get
in a cancellable state if you call WdfRequestMarkCancelable(). Since
you are already setting up a WDFQUEUE to hold the IOs that are in
flight on the hardware, you don’t need to do that, since the holding
queue will handle cancellation. Just preprocess your IO, start it on
your hardware, and forward it to your holding queue.

I’m guessing that if you have the timer timeout or the IO cancelled,
you need to do approximately the same things to the hardware to clear
the pending IO from it. You can register an EvtIoCanceledOnQueue
callback on your holding queue, as Peter mentioned, so that you can
tickle the hardware to remove a cancelled IO (and clean up any of your
own state).

Here’s where it gets a bit murky in my understanding. I have an old
post on this forum from Doron that said that it’s permissible to simply
complete a WDFREQUEST while it’s on a WDFQUEUE. Doron, is that right?
Can Diane call WdfRequestComplete (or one of it’s siblings) without
removing the WDFREQUEST from the WDFQUEUE it’s living on when she
determines that her hardware is done with it?

Hope this helps,
Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

So if it's a serial queue that's been stopped so it won't deliver requests,
you could just call WdfRequestComplete(), but if it's a manual queue, you
have to use the crazy WdfIoQueueFindRequest() loop with your own lock around
the loop in order to retrieve the WDFREQUEST so you can complete it in
compliance with the contract?

You guys *almost* created a useful CSQ for work-in-process in the manual
queue, but it's such a pain to use the way you've defined it, it's just not
worth it.

About the serial queue that's been stopped with
WdfIoQueueStopSynchronously() right after it's been created, is that a valid
replacement for the manual queue for a CSQ for in-process WDFREQUESTs?

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

"Doron Holan" wrote in message
news:xxxxx@ntdev...
It can be completed as long as it has not been marked cancelable by the
driver. If the request is on a manual queue, it must retrieved before
completion.

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: Philip D. Barila
Sent: Thursday, October 23, 2008 11:34 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] WDF queueing

Here's where it gets a bit murky in my understanding. I have an old
post on this forum from Doron that said that it's permissible to simply
complete a WDFREQUEST while it's on a WDFQUEUE. Doron, is that right?
Can Diane call WdfRequestComplete (or one of it's siblings) without
removing the WDFREQUEST from the WDFQUEUE it's living on when she
determines that her hardware is done with it?

I was hoping that the queues would simplify the logic for timing out requests that the hardware didn’t return to me. But it sure doesn’t seem that way. Previous implementation is to have a good old linked list of IRPs being service by the hardware, and when the periodic timer runs, it goes through the list, decrements the timer count for each, removes those timed out and completes them (leaving out some details here). With the manual queue I will still have to spinlock the thing to prevent the timer from working on a request that is being completed elsewhere. But now I have to do this business of removing each request from the queue so I can decrement the timer, then putting in back on. Plus, since it is a manual queue, in the non-error case, some internal function is going to have to walk the queue via WdfIoQueueFindRequest for each of those requests during Request completion.

Am I missing something? Not liking this solution much…

Diane

If you weren’t doing timeouts then it might simplify things. Given that you need some cancellation callback so you can abort the request and clean up, and that you need to periodically walk the list of requests from a timer, just doing a list seems more reasonable.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@earthlink.net
Sent: Thursday, October 23, 2008 11:24 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WDF queueing

I was hoping that the queues would simplify the logic for timing out requests that the hardware didn’t return to me. But it sure doesn’t seem that way. Previous implementation is to have a good old linked list of IRPs being service by the hardware, and when the periodic timer runs, it goes through the list, decrements the timer count for each, removes those timed out and completes them (leaving out some details here). With the manual queue I will still have to spinlock the thing to prevent the timer from working on a request that is being completed elsewhere. But now I have to do this business of removing each request from the queue so I can decrement the timer, then putting in back on. Plus, since it is a manual queue, in the non-error case, some internal function is going to have to walk the queue via WdfIoQueueFindRequest for each of those requests during Request completion.

Am I missing something? Not liking this solution much…

Diane


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I would hope you don’t like this solution. How about placing the time in
each request queued? When one exceeds the time limit, you can then grab a
spinlock to remove it from the queue. I think the queues provided by KMDF
should handle the spinlock for you and should have a non-locking accessor
capability to keep it on the list while you check for the time expiring.
The primary rule is that once you find one to take off the queue, you should
expect it may not be there when you actually try to get it.

wrote in message news:xxxxx@ntdev…
>I was hoping that the queues would simplify the logic for timing out
>requests that the hardware didn’t return to me. But it sure doesn’t seem
>that way. Previous implementation is to have a good old linked list of
>IRPs being service by the hardware, and when the periodic timer runs, it
>goes through the list, decrements the timer count for each, removes those
>timed out and completes them (leaving out some details here). With the
>manual queue I will still have to spinlock the thing to prevent the timer
>from working on a request that is being completed elsewhere. But now I
>have to do this business of removing each request from the queue so I can
>decrement the timer, then putting in back on. Plus, since it is a manual
>queue, in the non-error case, some internal function is going to have to
>walk the queue via WdfIoQueueFindRequest for each of those requests during
>Request completion.
>
> Am I missing something? Not liking this solution much…
>
> Diane
>

wrote in message news:xxxxx@ntdev…
> I was hoping that the queues would simplify the logic for timing out
> requests that the hardware didn’t return to me. But it sure doesn’t seem
> that way. Previous implementation is to have a good old linked list of
> IRPs being service by the hardware, and when the periodic timer runs, it
> goes through the list, decrements the timer count for each, removes those
> timed out and completes them (leaving out some details here). With the
> manual queue I will still have to spinlock the thing to prevent the timer
> from working on a request that is being completed elsewhere. But now I
> have to do this business of removing each request from the queue so I can
> decrement the timer, then putting in back on. Plus, since it is a manual
> queue, in the non-error case, some internal function is going to have to
> walk the queue via WdfIoQueueFindRequest for each of those requests during
> Request completion.
>
> Am I missing something? Not liking this solution much…
>
> Diane
>

Yes IMHO your design is a bit unjustified.
If the target device can handle requests one by one, then you
typically want to timeout only the one current request, not all other
waiting in the queue.
This “in-flight” request is removed from the waiting queue before processing
(or several requests, if the device has a serialized pipeline).

If the device can handle N requests in parallel, you remove these N requests
from the waiting queue and put them in some other structure (array or list
or another queue).

The point is that the queue is used to hold requests that can be canceled
automagically.
Requests removed off the queue and being handled on the device can be also
made cancelable (when the timeout is long), but you do this in a different
way, as this may involve touching the hardware.

Regards,
–PA

I think you'll have more success with a WDFTIMER than implementing your own
timeout logic. Just beware of how you allocate the timer, you can allocate
it as part of your preprocessing for each IO, but that falls down when you
have very high IO rates, because the WDFTIMER gets deleted by a passive
level work item, and if you are pushing the system hard enough, the passive
level work items never get to run and you end up with zillions of them in a
pending delete state, and you can't allocate a new one. We discovered that
one in a test harness that has really tested the limits of KMDF.

Keep in mind that our test harness is intended to drive HBAs and attached
disk drives at maximum speed. Our current setup involves an
EvtIoInCallerContext that locks down the UM buffers (because we have to do
direct DMA to any arbitrary buffer, we use a METHOD_BUFFERED IOCTL with a
command structure that contains embedded pointers for the data in and data
out buffers) and forwards the WDFREQUEST to a parallel WDFQUEUE. The
EvtIoDeviceControl preprocesses the IOs by grabbing an IO resource blob
(which contains, among other things, a pre-allocated SGL buffer and a
WDFTIMER), building the SGL by calling BuildScatterGatherList, and then
starting the IO on the hardware or putting the IO on a ready list. If it's
started on the hardware, we start the attached timer and mark it
cancellable. If it's on the ready list, it's just marked cancellable. In
either case, we have the appropriate callbacks to tear everything down and
put back what we need. Because the hardware capacity for IOs is relatively
small (511 is the biggest HBA we've done so far), we just keep IOs in flight
in an array, and count on the timer/cancellation callbacks to tell us we
need to abort an IO.

If I had some form of WDF container that managed the cancellation for me,
but didn't have the unpleasant contract of a manual WDFQUEUE, I could do
away with the dance of WdfRequestMarkCancelable / EvtRequestCancel /
WdfRequestUnmarkCancelable. My ideal container would allow me to stop the
timer and call WdfRequestComplete and friends without concern for the
container, it would "just work". I'd still have to have the
EvtIoCanceledOnQueue, but it's still simpler than what I have.

So back to Doron and/or Peter, will an automatic WDFQUEUE that has been
stopped give me that behavior, or is that abusing the framework?

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

wrote in message news:xxxxx@ntdev...
>I was hoping that the queues would simplify the logic for timing out
>requests that the hardware didn't return to me. But it sure doesn't seem
>that way. Previous implementation is to have a good old linked list of
>IRPs being service by the hardware, and when the periodic timer runs, it
>goes through the list, decrements the timer count for each, removes those
>timed out and completes them (leaving out some details here). With the
>manual queue I will still have to spinlock the thing to prevent the timer
>from working on a request that is being completed elsewhere. But now I
>have to do this business of removing each request from the queue so I can
>decrement the timer, then putting in back on. Plus, since it is a manual
>queue, in the non-error case, some internal function is going to have to
>walk the queue via WdfIoQueueFindRequest for each of those requests during
>Request completion.
>
> Am I missing something? Not liking this solution much...
>
> Diane
>

My understanding of this has always been that you can only complete requests you own, and you do not own a request that is in a queue [no matter what the flavor]- you've given ownership of it back to the framework. Only once it has been presented to you again in a callback [or by retrieval by you, which again removes it from the queue] do you own it.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Philip D. Barila
Sent: Friday, October 24, 2008 9:18 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] WDF queueing

I think you'll have more success with a WDFTIMER than implementing your own
timeout logic. Just beware of how you allocate the timer, you can allocate
it as part of your preprocessing for each IO, but that falls down when you
have very high IO rates, because the WDFTIMER gets deleted by a passive
level work item, and if you are pushing the system hard enough, the passive
level work items never get to run and you end up with zillions of them in a
pending delete state, and you can't allocate a new one. We discovered that
one in a test harness that has really tested the limits of KMDF.

Keep in mind that our test harness is intended to drive HBAs and attached
disk drives at maximum speed. Our current setup involves an
EvtIoInCallerContext that locks down the UM buffers (because we have to do
direct DMA to any arbitrary buffer, we use a METHOD_BUFFERED IOCTL with a
command structure that contains embedded pointers for the data in and data
out buffers) and forwards the WDFREQUEST to a parallel WDFQUEUE. The
EvtIoDeviceControl preprocesses the IOs by grabbing an IO resource blob
(which contains, among other things, a pre-allocated SGL buffer and a
WDFTIMER), building the SGL by calling BuildScatterGatherList, and then
starting the IO on the hardware or putting the IO on a ready list. If it's
started on the hardware, we start the attached timer and mark it
cancellable. If it's on the ready list, it's just marked cancellable. In
either case, we have the appropriate callbacks to tear everything down and
put back what we need. Because the hardware capacity for IOs is relatively
small (511 is the biggest HBA we've done so far), we just keep IOs in flight
in an array, and count on the timer/cancellation callbacks to tell us we
need to abort an IO.

If I had some form of WDF container that managed the cancellation for me,
but didn't have the unpleasant contract of a manual WDFQUEUE, I could do
away with the dance of WdfRequestMarkCancelable / EvtRequestCancel /
WdfRequestUnmarkCancelable. My ideal container would allow me to stop the
timer and call WdfRequestComplete and friends without concern for the
container, it would "just work". I'd still have to have the
EvtIoCanceledOnQueue, but it's still simpler than what I have.

So back to Doron and/or Peter, will an automatic WDFQUEUE that has been
stopped give me that behavior, or is that abusing the framework?

Phil

Philip D. Barila
Seagate Technology LLC
(720) 684-1842
As if I need to say it: Not speaking for Seagate.

wrote in message news:xxxxx@ntdev...
>I was hoping that the queues would simplify the logic for timing out
>requests that the hardware didn't return to me. But it sure doesn't seem
>that way. Previous implementation is to have a good old linked list of
>IRPs being service by the hardware, and when the periodic timer runs, it
>goes through the list, decrements the timer count for each, removes those
>timed out and completes them (leaving out some details here). With the
>manual queue I will still have to spinlock the thing to prevent the timer
>from working on a request that is being completed elsewhere. But now I
>have to do this business of removing each request from the queue so I can
>decrement the timer, then putting in back on. Plus, since it is a manual
>queue, in the non-error case, some internal function is going to have to
>walk the queue via WdfIoQueueFindRequest for each of those requests during
>Request completion.
>
> Am I missing something? Not liking this solution much...
>
> Diane
>

---
NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
OSR Seminars – OSR

To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum