Blocking IO and parallel dispatching

Hi,
I am writing an UMDF2 driver which accesses some legacy PCI board.
Besides reading and writing PCI bar memory this driver needs to handle occasional interrupts from the board.
For compatibility reasons the application needs to be notified about incoming interrupts knowing that these should be processed transparrently by the driver in an ideal worls.
Would it be possible to

  • initialize the default queue with WdfIoQueueDispatchParallel
  • Introduce an IOCTL WAIT_FOR_INTERRUPT

    case WAIT_FOR_INTERRUPT:
    // Store request in the device context so it can be completed later
    // Do noting to mark request as pending, complete the request in the DPC of the interrupt
    break;
    case READ_REGISTER:

    CASE WRITE_REGISTER:

and then have the application open a thread which issues a blocking IoControl with WAIT_FOR_INTERRUPT which only returns if the request is completed from the DPC routine handling the interrupt.

My question is:
If another thread of the application calls an IOControl request with e.g. READ_REGISTER, will this request be handled by the driver even though another request in the same queue is not completed? I have initialized the default queue as WdfIoQueueDispatchParallel, but does this mean that this request reaches the driver and can be completed emediatelly?
How does WdfIoQueueDispatchParallel relate to Overlapped IO?
Thank you and all the best!

I have initialized the default queue as WdfIoQueueDispatchParallel, but does this mean that this request reaches the driver and can be completed emediatelly?

Yes.

How does WdfIoQueueDispatchParallel relate to Overlapped IO?

Overlapped I/O is the means of a user app requesting asynchronous handling of an I/O operation. It tells Windows (and the driver): “You do not NEED to complete this request before you return control to me.”

When the Framework receives a Request with overlapped I/O is puts the Request on your driver’s Queue, and the I/O Manager returns “status pending” to the Requesting thread, and that thread continues running.

Parallel or Sequential dispatching are only vaguely related to Overlapped I/O. These determine how many Requests can be in progress (held without being completed) by your driver from a given Queue at a time.

That’s the world’s shortest explanation of what is, in general, a reasonably complicated topic. If that doesn’t answer your question, feel free to ask more.

Peter

Also, from the UM application’s point of view, opening a handle for OVERLAPPED IO does some other things too. The UM app can still use what amounts to blocking IO by immeditaly calling GetOverlappedResult (a event handle or polling loop is required) but importantly, it can now do what you want - send multiple IRPs through the same handle and have them completed out of order

sAllow me to make one other comment:

// Store request in the device context so it can be completed later
// Do noting to mark request as pending, complete the request in the DPC of the interrupt

That first line should be “move the request into a manual queue”. Not only does that relieve you of the responsibility of managing what might be a list of several requests, it also automatically handles cancellation. Your DPC merely has to remove the top entry in the manual queue. If there’s nothing in the queue, then whatever requests arrived must have been canceled.

Thanks for these helpful answers.
I’’ go for this approach ten and yes, I will use a manual queue.

Out of interest.

I have a parallel queue for my IRP_MJ_READ requests and in the request handler I forward those request to a manual queue,

In my DPC I remove the requests from the manual queue, handle them and complete them.

Does that give me asynchronous IO?

Sure.

But your apps have to also be in async mode. If they aren’t your io will be
synchronous from the app perspective.

Mark Roddy

I see.

I am just changing my test apps to deal with this.

Thank you.