From: Edward Dekker [dekker@eclectic-eng.com]
Sent: Friday, August 13, 1999 7:28 PM
To: ntdev@atria.com
Cc: Chris Cant; Donald Burn; joseph m. newcomer
Subject: Re: [ntdev] Pending IRPs

<<< Oops  -- I will try sending this again.  My mail program didn't like a
piece of text pasted in from Framemaker. Ed>>>

At 03:03 PM 8/13/99 +0100, Chris Cant wrote:
>Can someone clear up the use of the IRP PendingReturned flag?


>It seems to be standard practice to include this code in an IRP completion
>routine.  I'm not sure why.
>        if(Irp->PendingReturned)
>                IoMarkIrpPending(Irp);
>


Chris,  some information from my book may help.

Ed


From Chapter 23  Developing Windows NT Device Drivers: A Programmer's
Handbook,  by Edward Dekker and Joseph Newcomer,  Addison Wesley 1999,
ISBN 0-201-69590-1

Use of IoMarkIrpPending 

One piece of functionality in the previous list is extremely important.
Omitting this from a driver that calls a lower-level driver will lead to
certain disaster. The IoCompletion handler must contain the following if
statement:

    if(Irp->PendingReturned)
        IoMarkIrpPending(Irp);

This if statement must be present in any completion routine called in a
driver that calls lower-level drivers. It has the added charm that if you
put it into a driver that does not call a lower-level driver, no harm is
done. Thus it should be placed in every completion routine.
Assume your driver has already called IoMarkIrpPending for the IRP, before
it passed the IRP down to a lower level. When you initially called
IoMarkIrpPending, it set an internal bit in the current IRP Stack frame
(SL_PENDING_RETURNED in the Control field). The I/O Manager scanned the IRP
Stack when the IRP was completed by the lower-level driver. For each IRP
Stack entry with this bit set, the PendingReturned flag is set and the
completion routine is called. The Irp>PendingReturned value indicates that
a lower-level driver called IoMarkIrpPending to mark this IRP as pending
and returned STATUS_MORE_PROCESSING_REQUIRED. 
The IoMarkIrpPending routine is called to propagate the pending status to
the current IRP Stack frame. Without this statement, there is the chance
that drivers layered above this driver will either process this IRP
incorrectly or hang. It is required because of an optimization in the I/O
Manager.
When the I/O Manager completes an I/O request to an application program, it
must do some of the final completion processing in the thread of the
caller. The I/O Manager can queue a Kernel-mode :APC (:Asynchronous
Procedure Call) to the thread to force the thread context to switch to the
callers thread. This is an expensive operation. The I/O Manager uses two
conditions as a heuristic to determine that the original thread is still
the current thread: 

The state of the PendingReturned flag 
Knowing whether the original application call was a synchronous call or an
asynchronous call

To skip the APC, the I/O operation must have been synchronous and the IRP
must not have been completed asynchronously (that is, the PendingReturned
value must be FALSE). If the driver is the second (or lower) driver in a
chain of drivers (with either a higher-level driver or a Filter Driver
layered above it), the higher-level driver must be informed if there was
any asynchronous activity in the lower-level driver. To accomplish this,
when the lower-level driver completes, your driver must include the
statements shown previously; otherwise, the PendingReturned flag state will
be lost. Since the I/O Manager will never not see the PendingReturned flag
set to TRUE, it will assume that there was no asynchronous operation
involved in the processing of the IRP and that the callers thread is the
thread that is still executing. The I/O Manager will do the completion
processing in whatever thread happens to be current. In so doing, it will
do some unknowable damage (the thread might be a kernel thread), and the
thread that issued the I/O operation will never wake up.





-- 
Edward Dekker
Eclectic Engineering,  Inc
603 878-6125 Voice                   603 878-4897  FAX
dekker@eclectic-eng.com           www.eclectic-eng.com
----------------------------------------------------------
Co-Author of "Developing Windows NT Device Drivers: A Programmers Handbook"

see www.eclectic-eng.com for details
====================================
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[ To unsubscribe, send email to ntdev-request@atria.com with body
UNSUBSCRIBE (the subject is ignored). ]
