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


Синхронизация кода отмены и завершения

Если драйвер вызывает WdfRequestMarkCancelable или WdfRequestMarkCancelableEx для отмены запроса ввода-вывода, может возникнуть проблема синхронизации. Например, драйвер и устройство могут выполнять операции ввода-вывода устройства асинхронно с помощью функций обратного вызова EvtInterruptIsr и EvtInterruptDpc, а функции обратного вызова EvtInterruptDpc и EvtRequestCancel могут содержать вызовы WdfRequestComplete.

Драйвер должен вызывать WdfRequestComplete только один раз, чтобы завершить или отменить запрос. Но если функции обратного вызова EvtInterruptDpc и EvtRequestCancel не синхронизированы друг с другом, платформа может вызывать одну, а другая выполняется.

Избегайте этой проблемы, если драйвер использует автоматическую синхронизацию платформы, так как автоматическая синхронизация гарантирует, что функции обратного вызова будут вызываться одновременно.

Если драйвер не использует автоматическую синхронизацию платформы, он может использовать блокировки платформы для синхронизации кода отмены и завершения.

Независимо от того, использует ли драйвер автоматическую синхронизацию платформы или обеспечивает собственную синхронизацию, функция обратного вызова EvtRequestCancel драйвера должна вызвать WdfRequestComplete , чтобы отменить запрос. Функция обратного вызова EvtInterruptDpc драйвера должна вызывать WdfRequestUnmarkCancelable следующим образом:

Status = WdfRequestUnmarkCancelable(Request);
if( Status != STATUS_CANCELLED ) {
    WdfRequestComplete(Request, RequestStatus);
    }

Этот код гарантирует, что драйвер не вызывает WdfRequestComplete , чтобы завершить запрос, если драйвер уже вызвал его для отмены запроса.

Дополнительные сведения о правилах, которым должен следовать ваш драйвер при вызове WdfRequestUnmarkCancelable, см. в разделе WdfRequestUnmarkCancelable.