Share via


I/O 要求の取り消し

デバイスの進行中の I/O 操作 (ディスクから複数のブロックを読み取る要求など) は、アプリケーション、システム、またはドライバーによって取り消すことができます。デバイスの I/O 操作が取り消されると、I/O マネージャーは、その I/O 操作に関連付けられている未処理の I/O 要求を、すべて取り消そうとします。デバイスのドライバーは、I/O マネージャーが I/O 要求を取り消そうとしたときに通知を受けるように登録できます。これにより、ドライバーは、所有している各要求の完了状態を HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED に設定して完了することで、その要求を取り消すことができます。

フレームワークは、フレームワークベースのドライバーの取り消し作業の一部を処理します。デバイスの I/O 操作が取り消されると、フレームワークは、取り消された操作に関連付けられている次の I/O 要求を (完了状態を HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED) に設定して) 完了させます。

  • フレームワークがドライバーの既定の I/O キューに配置した未送信の I/O 要求。

  • ドライバーが IWDFIoQueue::ConfigureRequestDispatching を呼び出したために、フレームワークが別のキューに転送した未送信の I/O 要求。

これらの要求はフレームワークによって取り消されるため、ドライバーには送信されません。

フレームワークが I/O 要求をドライバーに送信した後は、そのドライバーが要求を所有するため、フレームワークはその要求を取り消すことができません。この時点で I/O 要求を取り消すことができるのはドライバーのみですが、フレームワークは要求を取り消す必要があることをドライバーに通知する必要があります。ドライバーは、IRequestCallbackCancel::OnCancel コールバック関数を提供することで、この通知を受け取ります。

ドライバーは、I/O キューから I/O 要求を受信したときに、その要求を処理せずに、後で処理するために同じ I/O キューまたは別の I/O キューに再度追加する場合があります。たとえば、フレームワークが I/O 要求をドライバーのいずれかの要求ハンドラーに渡し、この後、ドライバーが IWDFIoRequest::ForwardToIoQueue を呼び出して要求を異なるキューに配置するか、IWDFIoRequest2::Requeue を呼び出して要求を同じ同じキューに戻す場合があります。

このような場合、I/O 要求は I/O キュー内にあるため、フレームワークが要求を取り消すことができます。ただし、要求が存在する I/O キューに対してドライバーがコールバック関数を登録している場合、フレームワークは、関連付けられている I/O 操作が取り消されるときに、要求を取り消すのではなく、このコールバック関数を呼び出します。フレームワークがドライバーのコールバック関数を呼び出した場合は、ドライバーが要求を取り消す必要があります。

つまり、I/O 操作が取り消されると、フレームワークは常に、ドライバーに送信されていない関連付けられている I/O 要求をすべて取り消します。ドライバーが要求を受け取ってからキューに戻した場合、フレームワークは、ドライバーがその I/O キューに対してコールバック関数を提供していない限り、その要求を取り消します (要求がキュー内にある場合)。

MarkCancelable の呼び出し

ドライバーは、IWDFIoRequest::MarkCancelable を呼び出して IRequestCallbackCancel::OnCancel コールバック関数を登録できます。ドライバーが MarkCancelable を呼び出した後に、要求に関連付けられている I/O 操作が取り消されると、フレームワークはドライバーの OnCancel コールバック関数を呼び出して、ドライバーが I/O 要求を取り消すことができるようにします。

ドライバーは、要求を比較的長い時間所有する場合、MarkCancelable を呼び出す必要があります。たとえば、デバイスの応答を待機する必要がある場合、単一の要求を受信したときにそのドライバーが作成した一連の要求を下位のドライバーが完了するまで待機する必要がある場合などがあります。

ドライバーが MarkCancelable を呼び出さない場合、あるいは MarkCancelable を呼び出した後に IWDFIoRequest::UnmarkCancelable を呼び出す場合、ドライバーは要求の取り消しを認識できないため、通常どおりに要求を処理します。

IsCanceled の呼び出し

ドライバーは、MarkCancelable を呼び出して OnCancel コールバック関数を登録していない場合、IWDFIoRequest2::IsCanceled を呼び出して、I/O マネージャーが I/O 要求を取り消そうとしたかどうかを判別できます。IsCanceled が TRUE を返した場合、ドライバーは要求を取り消す必要があります。

たとえば、受信した大規模な読み込み要求または書き込み要求を複数の小さな要求に分割するドライバーが、受信した要求に対して MarkCancelable を呼び出していない場合、ドライバーの I/O ターゲットで小さな要求の処理が終了するたびに IsCanceled を呼び出すことができます。

要求の取り消し

I/O 要求の取り消しには、次の任意の操作が必要になる場合があります。

  • 進行中の I/O 操作を中止する。

  • 要求を I/O ターゲットに転送しない。

  • IWDFIoRequest::CancelSentRequest を呼び出して、ドライバーが前に I/O ターゲットに送信した要求の取り消しを試行する。

ドライバーは、フレームワークから受信した要求オブジェクトの I/O 要求を取り消す場合、常に IWDFIoRequest::Complete または IWDFIoRequest::CompleteWithInformation を、CompletionStatus パラメーターを HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED) に設定して呼び出すことによって、要求を完了させる必要があります。ドライバーが IWDFDevice::CreateRequest を呼び出して要求オブジェクトを作成した場合、ドライバーは要求を完了させる代わりに IWDFObject::DeleteWdfObject を呼び出します。