Share via


送信済み要求のキャンセルの同期

ドライバーが I/O ターゲットに転送した I/O 要求を取り消そうとするとき、ドライバーは WdfRequestCancelSentRequest メソッドに有効な要求ハンドルを渡すことを保証する必要があります。 ドライバーの CompletionRoutine コールバック関数が WdfRequestComplete (要求オブジェクトの削除を試みる) を呼び出すので、I/O ターゲットが要求を完了すると、要求ハンドルが無効になります。

この問題を回避するために、ドライバーは、要求オブジェクトのコレクションを作成するなどして、I/O ターゲットに送信された要求を追跡できます。 ドライバーは、WdfSpinLockAcquire を呼び出してコレクションへのアクセスを同期できます。

ドライバーの CompletionRoutine コールバック関数が呼び出されると、ロックが取得され、完了した要求のハンドルがコレクションから削除され、WdfSpinLockRelease が呼び出されてロックが解放されます。

ドライバーが I/O ターゲットに転送した要求を取り消そうとする前に、ドライバーは次のことができます。

  1. WdfSpinLockAcquire を呼び出してスピン ロックを取得します。

  2. ドライバーの完了ルーチンが要求を完了し、コレクションからハンドルを削除していないことを確認するために、コレクション内の要求オブジェクトのハンドルを検索します。

  3. WdfObjectReference を呼び出して、オブジェクトを削除できないように要求オブジェクトの参照カウントを増分します。

  4. WdfSpinLockRelease を呼び出してスピン ロックを解放します。

  5. WdfRequestCancelSentRequest を呼び出します。

  6. WdfObjectDereference を呼び出して、オブジェクトの参照カウントを減らします。

このシーケンスにより、ドライバーが WdfRequestCancelSentRequest を呼び出す前に I/O ターゲットが要求を完了した場合、ドライバーの CompletionRoutine コールバック関数が WdfRequestComplete を呼び出した場合でも、要求のハンドルは (参照カウントが増加するため) 引き続き有効になります。