新手关于IoMarkIrpPending作用的疑问,望达人解惑,该如何解决

新手关于IoMarkIrpPending作用的疑问,望达人解惑
近日读《Programming   the   Microsoft   Windows   Driver   Model》,其中第5章《I/O请求包》-   第3节《完成I/O请求》-   最后一段介绍了何时需使用函数IoMarkIrpPending

我想问下几个问题
1.   异步Irp是不是无论PendingReturnd设置与否,驱动的完成例程都是在APC里调用的?

2.   同步Irp的完成例程是不是根据PendingReturned来判断需不需要APC?

3.   PendingReturned和IoMarkIrpPending是不是为了优化同步Irp的完成效率,也就是在有些时候避免APC而存在的?


------解决方案--------------------
1. 排队一个APC是相对昂贵的。设想一下,不是直接返回STATUS_PENDING,而是派遣例程自己调用IoCompleteRequest并返回某个其它状态。在这种情况下,IoCompleteRequest的调用者将与IoCallDriver的调用者处于同一个线程上下文中。因此就没有必要排队一个APC。另外,甚至没有必要调用KeSetEvent,因为如果I/O管理器没有得到派遣例程返回的STATUS_PENDING,它就不用等待某个事件。如果IoCompleteRequest恰好知道发生的这种情况,它将优化这个处理以避免调用APC。这就是IoMarkIrpPending的来处。

2.IoCompleteRequest查看PendingReturned标志。如果该标志设置,并且如果IRP是那种可以以异步方式完成的IRP,那么IoCompleteRequest将简单地返回其调用者并不排队APC。它假定自己运行在IRP发起者的线程上下文中,并且派遣例程很快会返回一个非未决状态的代码给请求发起者。

3.调用IoMarkIrpPending然后同步完成IRP是正确的,效率会低一点。这样做的结果是IoCompleteRequest将排队APC,这个APC将改变事件的状态,但没有任何线程在这个事件上等待(其目的是使在调用KeSetEvent前保证这个事件存在)。这会降低一些效率,但不会有什么害处。