Handling IRPs 7: IoCompletion Routines and Asynchronous I/O Responses
来源:互联网 发布:金蝶软件连接数据库 编辑:程序博客网 时间:2024/06/05 22:28
IoCompletion Routines and Asynchronous I/O Responses
If a driver sets an IoCompletion routine for an IRP, theIoCompletion routine can check the value of the Irp->PendingReturned field to determine whether the IRP will be completed asynchronously.
If the value of the Irp->PendingReturned field is TRUE, theIoCallDriver routine will return (or has already returned) STATUS_PENDING. IfIrp‑>PendingReturned is FALSE, IoCallDriver has already returned with the value in theIrp‑>IoStatus.Status field. IoCompletion routines for intermediate drivers can similarly testIrp‑>PendingReturned to determine how the result of their forwarded request is being handled.
Drivers that complete I/O requests asynchronously sometimes must perform additional processing as the IRP moves back up the device stack. The following code sets anIoCompletion routine when it forwards an IRP to the next lower driver, then waits on an event. Thus, it handles an asynchronous response in the same manner as a synchronous one:
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
CatchIrpRoutine,
&event,
TRUE,
TRUE,
TRUE
);
status = IoCallDriver(DeviceObject, Irp);
//
// Wait for lower drivers to be done with the Irp.
// It’s important to note here that when you allocate
// memory for an event on the stack you must do a
// KernelMode wait instead of UserMode to prevent
// the stack from being paged out.
//
if (status == STATUS_PENDING) {
status = KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL
);
ASSERT(NT_SUCCESS(status));
status = Irp->IoStatus.Status;
}
return status;
In this case, the driver waits for an event that is set by itsIoCompletion routine. The driver must wait in kernel mode because the event was allocated on the stack. For performance reasons, drivers should wait on events only when IRPs complete asynchronously. TheKeWaitForSingleObject routine uses the system-wide dispatcher lock. This lock protects the signal state of events, semaphores, and mutexes, and consequently is used frequently throughout the operating system. Requiring the use of this lock for every synchronous I/O operation would unacceptably hinder performance.
The following code shows the IoCompletion routine set in the preceding fragment:
NTSTATUS
CatchIrpRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PKEVENT Event
)
{
if (IrpàPendingReturned) {
// Release waiting thread
KeSetEvent( Event, IO_NO_INCREMENT, FALSE );
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
The IoCompletion routine tests the value of theIrp->PendingReturned field. Based on this value, it sets an event only if STATUS_PENDING has been or will be returned to the caller. This avoids a call to theKeSetEvent routine, which uses the system-wide dispatcher lock.
The IoCompletion routine returns STATUS_MORE_PROCESSING_REQUIRED. This status indicates to the I/O Manager that the current driver must perform additional processing while it owns the IRP. The I/O Manager stops the upward completion of the IRP, leaving the I/O stack location in its current position. The current driver still owns the IRP and can continue to process it in another routine. When the driver has completely processed the IRP, it should call the IoCompleteRequest routine to continue IRP completion.
Ownership of the IRP is important because it determines whether the driver can access the IRP. As soon as a driver relinquishes ownership of the IRP, the IRP can be completed or freed on another thread, and any attempt by the driver to access the IRP can result in a system crash.- Handling IRPs 7: IoCompletion Routines and Asynchronous I/O Responses
- Handling IRPs 6: Asynchronous I/O Responses
- Handling IRPs 5: Synchronous I/O Responses
- handling IRPs 16: Debugging I/O Problems
- handling IRPs 13: I/O Control Codes (IOCTLs)
- Synchronous and Asynchronous I/O
- Handling IRPs: Definition 1: IRP as a Container for an I/O Request
- Synchronous and Asynchronous I/O解释
- Delphi文件学习 Standard Routines and I/O
- Delphi文件学习二 Standard Routines and I/O
- asynchronous i/o
- Asynchronous I/O 是什么?
- handling IRPs 15: Building IRPs
- Multi-threaded applications and asynchronous I/O(翻译)
- handling IRPs 17: Call to Action and Resources
- Handling IRPs: Introduction
- Handling IRPs 10: Optimizations
- oracle 中的 asynchronous I/O
- Handling IRPs 6: Asynchronous I/O Responses
- WPA Supplicant 在Windows下的编译
- JAVA I/O(一) File类
- Ubuntu 安装 sublime text 2
- Delphi7怎么样调用系统语音库 .
- Handling IRPs 7: IoCompletion Routines and Asynchronous I/O Responses
- Handling IRPs 8: Propagating the Pending Bit
- 解决flex4 spark 找不到外观错误
- FastReport的使用
- 线性回归 最小二乘 梯度下降 随机梯度下降
- Handling IRPs 9: Summary of Guidelines for Pending IRPs
- s3c6410 内存分配表
- Jsp和PHP共用80端口,整合Apache和Tomcat
- RTSP的例子终于跑通了,后面再花点时间梳理下,RTSP协议的学习就可以告一段落了,下一站SIP协议!~加油