Cancelando solicitações de E/S

A operação de E/S em andamento de um dispositivo (como uma solicitação para ler vários blocos de um disco) pode ser cancelada por um aplicativo, pelo sistema ou por um driver. Se a operação de E/S de um dispositivo for cancelada, o gerente de E/S tentará cancelar todas as solicitações de E/S não processadas associadas à operação de E/S. Os drivers do dispositivo podem se registrar para serem notificados quando o gerente de E/S tenta cancelar solicitações de E/S e os drivers podem cancelar as solicitações que possuem concluindo-as com uma status de conclusão de STATUS_CANCELLED.

A estrutura lida com alguns dos trabalhos de cancelamento para drivers baseados em estrutura. Se a operação de E/S de um dispositivo for cancelada, a estrutura concluirá as seguintes solicitações de E/S (com uma status de conclusão de STATUS_CANCELLED) associadas à operação cancelada:

  • Solicitações de E/S não entregues que a estrutura colocou na fila de E/S padrão do driver.

  • Solicitações de E/S não entregues que a estrutura encaminhou para outra fila porque o driver chamou WdfDeviceConfigureRequestDispatching.

Como a estrutura cancela essas solicitações, ela não as entrega ao driver.

Depois que a estrutura tiver entregue uma solicitação de E/S ao driver, o driver será proprietário da solicitação e a estrutura não poderá cancelá-la. Neste ponto, somente o driver pode cancelar a solicitação de E/S, mas a estrutura deve notificar o driver de que uma solicitação deve ser cancelada. Os drivers recebem essa notificação fornecendo uma função de retorno de chamada EvtRequestCancel .

Às vezes, um driver recebe uma solicitação de E/S de uma fila de E/S, mas, em vez de processar a solicitação, o driver requeusa a solicitação para a mesma fila de E/S para processamento posterior. Exemplos dessa situação incluem o seguinte:

Nesses casos, a estrutura pode cancelar a solicitação de E/S porque a solicitação está em uma fila de E/S. No entanto, se o driver tiver registrado uma função de retorno de chamada EvtIoCanceledOnQueue para a fila de E/S na qual a solicitação reside, a estrutura chamará a função de retorno de chamada, em vez de cancelar a solicitação, quando a operação de E/S associada estiver sendo cancelada. Se a estrutura chamar a função de retorno de chamada EvtIoCanceledOnQueue do driver, o driver deverá concluir a solicitação.

Em resumo, quando uma operação de E/S é cancelada, a estrutura sempre cancela todas as solicitações de E/S associadas que nunca foram entregues ao driver. Se o driver receber uma solicitação e, em seguida, requeuí-la, a estrutura cancelará a solicitação (se a solicitação estiver na fila), a menos que o driver forneça uma função de retorno de chamada EvtIoCanceledOnQueue para a fila de E/S.

Chamando WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx

Um driver pode chamar WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx para registrar uma função de retorno de chamada EvtRequestCancel . Se o driver tiver chamado WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx e se a operação de E/S associada à solicitação for cancelada, a estrutura chamará a função de retorno de chamada EvtRequestCancel do driver para que o driver possa cancelar a solicitação de E/S.

Um driver deve chamar WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx se ele tiver uma solicitação por um tempo relativamente longo. Por exemplo, um driver pode ter que aguardar a resposta de um dispositivo ou aguardar que drivers inferiores concluam um conjunto de solicitações que o driver criou quando recebeu uma única solicitação.

Se um driver não chamar WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx ou se um driver chamar WdfRequestUnmarkCancelable depois de chamar WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx, o driver não estará ciente do cancelamento e, portanto, manipulará a solicitação como normalmente faria.

Chamando WdfRequestIsCanceled

Se um driver não tiver chamado WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx para registrar uma função de retorno de chamada EvtRequestCancel , ele poderá chamar WdfRequestIsCanceled para determinar se o gerente de E/S tentou cancelar uma solicitação de E/S. Se WdfRequestIsCanceled retornar TRUE e o driver possuir a solicitação, o driver deverá cancelar a solicitação. Se o driver não possui a solicitação, ele não deve chamar WdfRequestIsCanceled.

Um driver que não chamou WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx pode chamar WdfRequestIsCanceled nas seguintes circunstâncias:

Cancelando a solicitação

Cancelar uma solicitação de E/S pode envolver qualquer uma das seguintes opções:

  • Interrompendo uma operação de E/S em andamento.

  • Não encaminhar a solicitação para um destino de E/S.

  • Chamar WdfRequestCancelSentRequest para tentar cancelar uma solicitação que o driver havia enviado anteriormente a um destino de E/S.

Se um driver estiver cancelando uma solicitação de E/S para um objeto de solicitação que o driver recebeu da estrutura, o driver sempre deverá concluir a solicitação chamando WdfRequestComplete, WdfRequestCompleteWithInformation ou WdfRequestCompleteWithPriorityBoost, com um parâmetro Status de STATUS_CANCELLED. (Se o driver chamado WdfRequestCreate criar um objeto de solicitação, o driver chamará WdfObjectDelete em vez de concluir a solicitação.)

Sincronizando o cancelamento

Para obter informações sobre como sincronizar o código que cancela solicitações de E/S, consulte: