サービス シンクとサービスのグループのオブジェクト
PortCls システム ドライバーは、ポート ドライバーとミニポート ドライバーの利点のために IServiceSink と IServiceGroup インターフェイスを実装します。 ポート ドライバーはこれらのインターフェイスを使用して、割り込み通知を独自のサービス ルーチンに配布し、ミニポート ドライバーには、同様の目的でこれらのインターフェイスを使用するオプションがあります。 IServiceSink オブジェクトはサービス ルーチンをカプセル化し、IServiceGroup オブジェクトは IServiceSink オブジェクトのグループを表します。 サービス グループはサービス リクエストを受信すると、そのリクエストを各サービス シンクに配布します。
IServiceGroup は IServiceSink から継承します。 サービス グループはサービス シンクでもあるため、サービス グループには他のサービス グループを含めることができますが、オーディオ ドライバーは通常この機能を使用しません。 現在、ポート ドライバーはサービス グループを使用して割り込みサービスの要求を逆多重化しますが、サービス グループの機能は十分に汎用的であるため、他の目的にも役立つ可能性があります。
ミニポート ドライバーの割り込みサービス ルーチン (ISR) は、ポート ドライバーで次の通知メソッドのいずれかを呼び出します:
通知方式は、サービス グループへのポインタを呼び出しパラメータとして受け取ります。 この呼び出し中に、ポート ドライバーはサービス グループの IServiceSink::RequestService 方式を呼び出し、遅延プロシージャ コール (DPC) をキューに入れます。 DPC が実行される時、サービス リクエストがサービス グループ内のすべてのメンバー オブジェクトに転送されます。
通常、ミニポート ドライバー コードでは、IServiceGroup インターフェイス 方式を呼び出す必要はありません。 ただし、ポート ドライバーはこれらのメソッドを呼び出して、ミニポート ドライバーから取得したサービス グループに独自の IServiceSink オブジェクトを追加します。 ミニポート ドライバーは、必要に応じてサービス グループ オブジェクトを作成し、それらのサービス グループを定期的なサービスが必要なミニポートおよびストリーム オブジェクトに関連付けます。 たとえば、WaveCyclic ミニポート ドライバーは、ストリーム オブジェクトを、IMiniportWaveCyclic::NewStream 方式への出力パラメーターとして指定するサービス グループに関連付けます。
WaveCyclic ミニポート ドライバーのコンテキストでは、すべてのストリームを 1 つのサービス グループに関連付けると、ポート ドライバーは 1 つの通知に基づいてすべてのストリームにサービスを提供します。 各ストリームを独自のサービス グループに関連付けることにより、割り込みサービス ルーチンは、DPC の実行中にポート ドライバーによってサービスされるストリームを選択できるようになります。
ミニポート ドライバーは、ポート ドライバーが次のいずれかの初期化方式を呼び出すと、そのサービス グループへの参照を出力します:
ポート ドライバーは、Init 呼び出しから取得したサービス グループに独自の IServiceSink オブジェクトを追加します。 後でミニポート ドライバーの ISR が 通知 を呼び出してそのサービス グループに通知を送信すると、サービス グループは通知をポート ドライバーの IServiceSink オブジェクトに転送する DPC をキューに入れます。次に、次のサービス方式のいずれかを呼び出して、ミニポート ドライバーに通知を転送します:
IMiniportDMus::Service (未使用)
ミニポート ドライバーは、ポート ドライバーが次のストリーム作成メソッドのいずれかを呼び出すときに、そのサービス グループへの参照も出力します:
IMiniportWaveCyclic::NewStream
前に説明したように、ミニポート ドライバーには、ストリームごとに異なるサービス グループを作成するか、すべてのストリームで単一のサービス グループを共有するかを選択できます。
次の方法は、MIDI および DMus ポート ドライバーがハードウェア割り込みのドロップを回避するのに役立ちます:
IPortMidi::RegisterServiceGroup
IPortDMus::RegisterServiceGroup
Init 方式の実行中、MIDI または DMus ミニポート ドライバーは通常、シンセサイザーを起動する前にポート ドライバーの RegisterServiceGroup 方式を呼び出します。 この呼び出しの目的は、ハードウェアが割り込みの生成を開始する前に、ポート ドライバーがサービス シンク オブジェクト (割り込みハンドラーを含む) をサービス グループに挿入できるようにすることです。 Init 方式はサービス グループ ポインタをポート ドライバに出力しますが、ポート ドライバがこのポインタを使用できるのは、Init から戻った後でのみです。
WavePci ポート ドライバーの場合、ポート オブジェクトは、IMiniportWavePci::NewStream 呼び出しから取得したサービス グループに独自の IServiceSink オブジェクトを追加します。 後でミニポート ドライバーの ISR が通知を呼び出してそのサービス グループに通知を送信すると、サービス グループは通知をポート ドライバーの IServiceSink オブジェクトに転送する DPC をキューに入れます。これにより、次に次の処理が行われます:
サービス 方式 IMiniportWavePciStream::Service を呼び出して、通知をミニポート ストリームに転送します。
起動の準備ができているピン上の位置イベントおよび/またはクロック イベントをトリガーします。
IServiceSink インターフェイスは、次の 1 つのメソッドをサポートします:
IServiceGroup インターフェイスは次の方式をサポートします:
IServiceGroup::CancelDelayedService
IServiceGroup::RequestDelayedService
IServiceGroup::SupportDelayedService
さらに、PortCls システム ドライバーは、新しいサービス グループ オブジェクトを作成するための PcNewServiceGroup 関数を提供します。 ただし、サービス シンク オブジェクトを作成するための同様の関数は存在しません。 ポート ドライバーは、メイン ポート オブジェクトの実装に IServiceSink インターフェイスを追加するだけです。オブジェクトが作成されると、サービス シンクも作成されます。 ポート ドライバーは、ミニポート ドライバーの Init または NewStream 方式から受け取るサービス グループに、ポート オブジェクトの IServiceSink インターフェイスを追加できます。 便宜上、ヘッダー ファイル Portcls.h は、IServiceSink インターフェイスと IServiceGroup インターフェイスをドライバー オブジェクトに追加するための IMP_IServiceSink 定数と IMP_IServiceGroup 定数を定義します。