Compartir a través de


Sincronización de la cancelación de solicitudes enviadas

Cuando un controlador intenta cancelar una solicitud de E/S que ha reenviado a un destino de E/S, el controlador debe asegurarse de que pasa un identificador de solicitud válido al método WdfRequestCancelSentRequest . El identificador de solicitud no es válido si el destino de E/S completa la solicitud, ya que la función de devolución de llamada CompletionRoutine del controlador llamará a WdfRequestComplete (que intenta eliminar el objeto de solicitud).

Para evitar este problema, el controlador puede realizar un seguimiento de las solicitudes que ha enviado al destino de E/S, por ejemplo, creando una colección de objetos de solicitud. El controlador puede llamar a WdfSpinLockAcquire para sincronizar el acceso a la colección.

Cuando se llama a la función de devolución de llamada CompletionRoutine del controlador, adquiere el bloqueo, quita el identificador de la solicitud completada de la colección y llama a WdfSpinLockRelease para liberar el bloqueo.

Antes de intentar cancelar una solicitud que el controlador ha reenviado a un destino de E/S, el controlador puede hacer lo siguiente:

  1. Llame a WdfSpinLockAcquire para adquirir un bloqueo de número.

  2. Busque el identificador del objeto de solicitud en la colección para asegurarse de que la rutina de finalización del controlador no ha completado la solicitud y quitado el identificador de la colección.

  3. Llame a WdfObjectReference para incrementar el recuento de referencias del objeto de solicitud para que no se pueda eliminar el objeto.

  4. Llame a WdfSpinLockRelease para liberar el bloqueo de número.

  5. Llame a WdfRequestCancelSentRequest.

  6. Llame a WdfObjectDereference para disminuir el recuento de referencias del objeto.

Esta secuencia garantiza que si el destino de E/S completa la solicitud antes de que el controlador llame a WdfRequestCancelSentRequest, el identificador de la solicitud sigue siendo válido (debido al recuento de referencias incrementada) incluso si la función de devolución de llamada CompletionRoutine del controlador llama a WdfRequestComplete.