Поделиться через


Синхронизация кода прерывания (UMDF 1)

Предупреждение

UMDF 2 является последней версией UMDF и заменяет UMDF 1. Все новые драйверы UMDF должны быть написаны с помощью UMDF 2. В UMDF 1 новые функции не добавляются, а поддержка UMDF 1 в более новых версиях Windows 10 ограничена. Универсальные драйверы Windows должны использовать UMDF 2.

Архивные примеры UMDF 1 можно найти в Windows 11 версии 22H2 — обновление примеров драйверов за май 2022 г.

Дополнительные сведения см. в разделе начало работы с помощью UMDF.

Весь код драйвера, который обращается к буферу данных прерываний, должен быть синхронизирован, чтобы доступ к данным одновременно выполнялась только одной подпрограммой.

Код прерывания можно синхронизировать с помощью блокировки прерываний вручную или автоматической сериализации обратного вызова.

Блокировка прерываний вручную

UMDF получает блокировку прерывания перед вызовом обратных вызовов OnInterruptIsr, OnInterruptDisable или OnInterruptEnable .

Если драйверу необходимо синхронизировать любой код с помощью блокировки прерываний, он вызывает IWDFInterrupt::AcquireInterruptLock и IWDFInterrupt::ReleaseInterruptLock. Например, драйвер получает и снимает блокировку прерываний в процедуре обратного вызова OnInterruptWorkItem с помощью этих методов. Однако в обратных вызовах диспетчеризации ввода-вывода (например , OnRead и OnWrite) драйвер сначала вызывает IWDFInterrupt::TryToAcquireInterruptLock , чтобы решить, следует ли ставить рабочий элемент в очередь или выполнять работу в одном потоке, чтобы избежать потенциальной взаимоблокировки. Пример сценария взаимоблокировки, который может быть вызван вызовом IWDFInterrupt::AcquireInterruptLock из контекста произвольного потока, см. в разделе Примечания статьи IWDFInterrupt::AcquireInterruptLock.

Если IWDFInterrupt::TryToAcquireInterruptLock возвращает значение TRUE, драйвер получил блокировку прерывания в том же потоке. В этом случае драйвер выполняет работу, требующую этой блокировки, а затем вызывает ReleaseInterruptLock. Если IWDFInterrupt::TryToAcquireInterruptLock возвращает значение FALSE, драйвер помещает рабочий элемент в очередь и выполняет работу в обратном вызове OnWorkItem . В этом случае рабочий элемент не должен использовать автоматическую сериализацию.

Использование автоматической сериализации

Драйвер UMDF может запросить автоматическую синхронизацию обратного вызова, вызвав IWDFDeviceInitialize::SetLockingConstraint с параметром LockType , равным WdfDeviceLevel.

Затем драйвер устанавливает для элемента AutomaticSerialization своей структуры WUDF_INTERRUPT_CONFIGзначение TRUE , прежде чем вызывать CreateInterrupt.

В результате UMDF сериализует обратные вызовы OnInterruptWorkItem драйвера с помощью очереди ввода-вывода, отмены запросов и обратного вызова файловых объектов. В этом сценарии UMDF использует блокировку обратного вызова вместо блокировки объекта на прерывание.