I/O cancellation: when does it matter?
Any time an IRP can be queued indefinitely or remain active on a device for a long time, the driver should support IRP cancellation. This allows the driver to remove and quickly complete an outstanding I/O request that a user has cancelled.
Drivers that don't support I/O cancellation (or that fail to complete I/O in a timely fashion) can cause applications to become unresponsive, causing the user to think the application is hung. Drivers that block user-mode threads with kernel-mode waits or don't implement cancellation at all can cause applications or the system to hang, often in a seemingly random way. Driver hangs are especially serious because they usually require the user to reboot the system.
Drivers for Windows 2000 and later releases can use cancel-safe IRP queues to implement cancellation. The cancel-safe IRP queuing functions (IoCsqXxx) provide a framework that handles cancellation properly so that race conditions do not occur. Drivers that use cancel-safe IRP queues do not need to implement a Cancel routine; instead, they supply driver-specific callback routines that manage queues and locks.
Drivers for earlier versions of Windows must implement a Cancel routine, and they should supply a locking mechanism rather than use the system-wide cancel spin lock.
- Support I/O cancellation in your driver, unless it merely forwards IRPs to a lower-level driver (which is responsible for canceling the IRP).
- If you're writing a driver for Windows 2000 or later, use cancel-safe IRP queuing in new drivers, and modify existing drivers to use the IoCsqXxx functions whenever possible.
- If your driver can't use the IoCsqXxx functions, supply a locking mechanism and implement a Cancel routine.
- Don't use the system-wide cancel spin lock unless your driver performs I/O very infrequently.