I/O 取消:在什么时候这很重要?
只要 IRP 可以被无限期排队或在设备上长时间保持活动,驱动程序就应该支持 IRP 取消。这允许驱动程序删除和快速完成用户已经取消的未决的 I/O 请求。
不支持 I/O 取消(或者无法快速完成 I/O)的驱动程序会导致应用程序无响应,从而导致用户认为应用程序被挂起。使用内核模式等待来阻塞用户模式线程的驱动程序或根本不实现取消的驱动程序会导致应用程序或系统挂起(这通常似乎是随机发生的)。驱动程序挂起的后果特别严重,因为它们通常需要用户重启系统。
用于 Windows 2000 和更高版本的驱动程序可以使用能够安全取消的 IRP 队列来实现取消。可以安全取消的 IRP 排队函数 (IoCsqXxx) 提供一个框架来正确处理取消,从而避免竞争条件发生。使用能够安全取消的 IRP 队列的驱动程序不需要实现 Cancel 例程;而是提供驱动程序特定的回调例程来管理队列和锁。
用于早期版本 Windows 的驱动程序必须实现一个 Cancel 例程,并且它们应该提供一种锁定机制,而不是使用系统范围的取消自旋锁。
您应该做什么?
| • | 在您的驱动程序中支持 I/O 取消(除非它仅仅将 IRP 转发给底层驱动程序,由底层驱动程序负责取消 IRP)。 |
| • | 如果您正在为 Windows 2000 或更高版本编写驱动程序,那么在新的驱动程序中使用能够安全取消的 IRP 排队,并在任何可能的时候修改现有的驱动程序以使用 IoCsqXxx 函数。 |
| • | 如果您的驱动程序不能使用 IoCsqXxx 函数,那么请提供一种锁定机制并实现一个 Cancel 例程。 |
| • | 不要使用系统范围的取消自旋锁(除非您的驱动程序极少执行 I/O)。 |
更多信息:
Windows 驱动程序中的取消逻辑
可以安全取消的 IRP 排队的控制流程
Windows Vista 和 Windows Server 2008:
I/O 完成/取消指南
驱动程序挂起验证程序