Synchronizace kódu pro zrušení a dokončení

Pokud ovladač volá WdfRequestMarkCancelable nebo WdfRequestMarkCancelableEx , aby bylo možné zrušit vstupně-výstupní požadavek, může dojít k problému se synchronizací. Ovladač a zařízení například můžou provádět vstupně-výstupní operace zařízení asynchronně pomocí funkcí zpětného volání EvtInterruptIsr a EvtInterruptDpc a funkce zpětného volání EvtInterruptDpc i EvtRequestCancel můžou obsahovat volání WdfRequestComplete.

Ovladač musí zavolat WdfRequestComplete pouze jednou, aby se žádost dokončila nebo zrušila. Ale pokud funkce zpětného volání EvtInterruptDpc a EvtRequestCancel nejsou vzájemně synchronizovány, architektura může volat jeden, zatímco druhý provádí.

Pokud ovladač používá automatickou synchronizaci architektury, je snadné se vyhnout tomuto problému, protože automatická synchronizace zajišťuje, že funkce zpětného volání budou volána po jednom.

Pokud ovladač nepoužívá automatickou synchronizaci frameworku, může k synchronizaci kódu pro zrušení a dokončení použít zámky frameworku.

Bez ohledu na to, jestli ovladač používá automatickou synchronizaci architektury nebo poskytuje vlastní synchronizaci, musí funkce zpětného volání EvtRequestCancel volat WdfRequestComplete a zrušit požadavek. Funkce zpětného volání EvtInterruptDpc ovladače by měla volat WdfRequestUnmarkCancelable následujícím způsobem:

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

Tento kód zajišťuje, že ovladač nevolá WdfRequestComplete k dokončení požadavku, pokud ovladač již volal, aby zrušil požadavek.

Další informace o pravidlech, která ovladač musí dodržovat při volání WdfRequestUnmarkCancelable, naleznete v tématu WdfRequestUnmarkCancelable.