Synchronizing Interrupt Code (UMDF 1)

Warning

UMDF 2 is the latest version of UMDF and supersedes UMDF 1. All new UMDF drivers should be written using UMDF 2. No new features are being added to UMDF 1 and there is limited support for UMDF 1 on newer versions of Windows 10. Universal Windows drivers must use UMDF 2.

The archived UMDF 1 samples can be found in the Windows 11, version 22H2 - May 2022 Driver Samples Update.

For more info, see Getting Started with UMDF.

All driver code that accesses the interrupt data buffer must be synchronized so that only one routine accesses the data at a time.

You can synchronize interrupt code by using either manual interrupt locking or automatic callback serialization.

Manual Interrupt Locking

UMDF acquires the interrupt lock before calling the OnInterruptIsr, OnInterruptDisable, or OnInterruptEnable callbacks.

If a driver needs to synchronize any code using the interrupt lock, it calls IWDFInterrupt::AcquireInterruptLock and IWDFInterrupt::ReleaseInterruptLock. For example, a driver acquires and releases the interrupt lock in its OnInterruptWorkItem callback routine by using these methods. However, in I/O dispatch callbacks (such as OnRead and OnWrite), the driver first calls IWDFInterrupt::TryToAcquireInterruptLock to decide whether to queue a work item or do the work in same thread to avoid potential deadlock. For an example of a deadlock scenario that can be caused by calling IWDFInterrupt::AcquireInterruptLock from an arbitrary thread context, see the Remarks section of IWDFInterrupt::AcquireInterruptLock.

If IWDFInterrupt::TryToAcquireInterruptLock returns TRUE, the driver has acquired the interrupt lock in the same thread. In this case, the driver performs the work that required that lock, and then calls ReleaseInterruptLock. If IWDFInterrupt::TryToAcquireInterruptLock returns FALSE, the driver queues a work item and performs the work in its OnWorkItem callback. In this case, the work item must not use automatic serialization.

Using Automatic Serialization

A UMDF driver can request automatic callback synchronization by calling IWDFDeviceInitialize::SetLockingConstraint with the LockType parameter set to WdfDeviceLevel.

The driver then sets the AutomaticSerialization member of its WUDF_INTERRUPT_CONFIG structure to TRUE before calling CreateInterrupt.

As a result, UMDF serializes the driver's OnInterruptWorkItem callbacks with I/O queue, request cancellation, and file object callback routines. In this scenario, UMDF uses the callback lock instead of a per-interrupt object lock.