When my ‘hardware’ (virtual connection to xen in this case) becomes
unavailable, I need to know when the wdf io queue has been stopped and
emptied, and when all calls to EvtIoDeviceControl (and any other
EvtIoXxx call too I guess) are complete.
The docs for WdfIoQueuePurgeSynchronously state that “The framework
cancels all requests that it has not delivered to the driver.”, which
takes care of the first requirement, but does that also imply that any
current call to EvtIoXxx is then completed too, or do I need to manage
synchronisation to that too? I would assume the former but don’t like
building drivers based on assumptions like that 
Note that I’m just talking about the call to EvtIoXxx being complete,
not the request itself which I can handle separately.
Thanks
James
Very interesting question… I’d be surprised to discover that it does.
I’ll be interested to hear the answer,
Peter
OSR
James Harper wrote:
The docs for WdfIoQueuePurgeSynchronously state that “The framework
cancels all requests that it has not delivered to the driver.”, which
takes care of the first requirement, but does that also imply that any
current call to EvtIoXxx is then completed too, or do I need to manage
synchronisation to that too? I would assume the former but don’t like
building drivers based on assumptions like that 
If you are in EvtIoXxxx handling a request, then clearly that request
has been delivered to the driver, and no longer belongs to the
framework. The framework can’t track it any more. It’s up to you to
handle that case. PurgeQueueSynchronously will return when the
undelivered requests are canceled. It doesn’t worry about delivered
requests.
Note that I’m just talking about the call to EvtIoXxx being complete,
not the request itself which I can handle separately.
If you are handling the request, then is there really any other
concern? Why would you care whether the EvtIo handler itself was finished?
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Consider the case in which you call and return from WdfIoQueuePurgeSynchronously on Processor A, while the code running on Processor B has JUST before your call on Processor A has dequeued a request and is about to call your EvtIo Event Processing Callback on Processor B.
Hmmmm… Very rare and very racy,
Peter
OSR
that condition is handled. the whole point of purge is that by the time it returns, all in flight requests are no longer being processed and a gate has been put up so that no new ones are presented (until you restart the queue)
d
>
that condition is handled. the whole point of purge is that by the
time it
returns, all in flight requests are no longer being processed and a
gate has
been put up so that no new ones are presented (until you restart the
queue)
Thanks for the confirmation Doron. After posting this I found that
WdfIoQueuePurgeSynchronously actually cancels any request that is
outstanding (eg WdfIoDeviceControl had finished and pended the routine)
and marked cancellable, which was unexpected but welcome behaviour. This
implies synchronisation with WdfIoXxx routines too. It makes my code a
whole lot simpler!
Thanks
James
i would be careful when you say the io queue APIs provide synchronization with the EvtIoXxx routines. that would seem to imply they are mutually exclusive, ie one cannot be called concurrently with another. rather, the io queue APIs provide state and runtime protection around the state of the queue and what will be presented to the driver.
d
>
James Harper wrote:
> The docs for WdfIoQueuePurgeSynchronously state that “The framework
> cancels all requests that it has not delivered to the driver.”,
which
> takes care of the first requirement, but does that also imply that
any
> current call to EvtIoXxx is then completed too, or do I need to
manage
> synchronisation to that too? I would assume the former but don’t
like
> building drivers based on assumptions like that 
If you are in EvtIoXxxx handling a request, then clearly that request
has been delivered to the driver, and no longer belongs to the
framework. The framework can’t track it any more. It’s up to you to
handle that case. PurgeQueueSynchronously will return when the
undelivered requests are canceled. It doesn’t worry about delivered
requests.
> Note that I’m just talking about the call to EvtIoXxx being
complete,
> not the request itself which I can handle separately.
If you are handling the request, then is there really any other
concern? Why would you care whether the EvtIo handler itself was
finished?
In my case the backend code running on xen (the ‘hardware’ from windows
pov) has ceased functioning, as determined by a missed heartbeat. I need
to make sure we don’t receive any further requests from userspace
(WdfIoQueuePurgeSynchronously) and wait until any outstanding call to
EvtIoDeviceControl is finished so I know that nothing is touching or
going to touch the ‘hardware’ or other internal data structures.
Spinlocks are great, but the less the better, and aren’t the solution in
all cases.
It’s a pain because it involved a whole lot of thinking for an almost
never executed code path (backend code crash in theory should never
happen).
James
Just ANOTHER thing to love about KMDF.
Peter
OSR