Objetos de receptor de servicio y grupo de servicios

El controlador del sistema PortCls implementa las interfaces IServiceSink e IServiceGroup para beneficiarse de los controladores de puerto y minipuerto. El controlador de puerto usa estas interfaces para distribuir las notificaciones de interrupción a sus propias rutinas de servicio y un controlador de miniporte tiene la opción de usar estas interfaces con fines similares. Un objeto IServiceSink encapsula una rutina de servicio y un objeto IServiceGroup representa un grupo de objetos IServiceSink. Cuando un grupo de servicios recibe una solicitud de servicio, distribuye la solicitud a cada uno de sus receptores de servicio.

IServiceGroup hereda de IServiceSink. Dado que un grupo de servicios también es un receptor de servicio, un grupo de servicios es capaz de contener otros grupos de servicios, aunque los controladores de audio normalmente no usan esta funcionalidad. Actualmente, los controladores de puerto usan grupos de servicio para desmultiplex solicitudes para el servicio de interrupción, aunque la funcionalidad de un grupo de servicios es lo suficientemente general como para que también sea útil para otros fines.

La rutina de servicio de interrupción (ISR) del controlador de miniporte llama a uno de los métodos de notificación siguientes en el controlador de puerto:

IPortDMus::Notify

IPortMidi::Notify

IPortWaveCíclico::Notify

IPortWavePci::Notify

El método de notificación toma un puntero al grupo de servicios como parámetro de llamada. Durante esta llamada, el controlador de puerto llama al método IServiceSink::RequestService del grupo de servicios, que pone en cola una llamada a procedimiento diferido (DPC). Cuando se ejecuta el DPC, reenvía la solicitud de servicio a todos los objetos miembro del grupo de servicios.

Normalmente, el código del controlador de miniporte no necesita llamar a ningún método de interfaz IServiceGroup . Sin embargo, el controlador de puerto llama a estos métodos para agregar sus propios objetos IServiceSink a los grupos de servicios que obtiene del controlador de miniport. Los controladores de minipuerto crean objetos de grupo de servicio según sea necesario y asocian esos grupos de servicios con objetos de minipuerto y secuencia que requieren mantenimiento periódico. Por ejemplo, un controlador de miniporte WaveCíclico asocia un objeto stream con el grupo de servicios que especifica como parámetro de salida al método IMiniportWaveCíclico::NewStream .

En el contexto de los controladores de minipuerto wavecíclicos, la asociación de todas las secuencias con un grupo de servicios hace que el controlador de puerto service todos los flujos se advíen en función de una sola notificación. La asociación de cada secuencia con su propio grupo de servicios permite que la rutina de servicio de interrupción seleccione la secuencia que el controlador de puerto atenderá durante la ejecución del DPC.

Un controlador de minipuerto genera una referencia a su grupo de servicios cuando el controlador de puerto llama a uno de los métodos de inicialización siguientes:

IMiniportDMus::Init

IMiniportMidi::Init

IMiniportWavePci::Init

El controlador de puerto agrega su propio objeto IServiceSink al grupo de servicios que obtiene de la llamada init . Cuando el ISR del controlador de minipuerto llama posteriormente a Notificar para enviar notificaciones a ese grupo de servicios, el grupo de servicios pone en cola un DPC que reenvía la notificación al objeto IServiceSink del controlador de puerto, que a su vez reenvía la notificación al controlador de minipuerto llamando a uno de los métodos de servicio siguientes:

IMiniportDMus::Service (no se usa)

IMiniportMidi::Service

IMiniportWavePci::Service

Un controlador de minipuerto también genera una referencia a su grupo de servicios cuando el controlador de puerto llama a uno de los siguientes métodos de creación de flujos:

IMiniportDMus::NewStream

IMiniportMidi::NewStream

IMiniportWaveCíclico::NewStream

IMiniportWavePci::NewStream

Como se explicó anteriormente, el controlador de minipuerto tiene la opción de crear un grupo de servicio diferente para cada secuencia o compartir un único grupo de servicios en todas las secuencias.

Los métodos siguientes ayudan a los controladores de puertos MIDI y DMus a evitar interrupciones de hardware:

IPortMidi::RegisterServiceGroup

IPortDMus::RegisterServiceGroup

Durante la ejecución de su método Init , un controlador de miniporte MIDI o DMus normalmente llama al método RegisterServiceGroup del controlador de puerto antes de iniciar el sintetizador. El propósito de esta llamada es permitir que el controlador de puerto inserte su objeto receptor de servicio (que contiene su controlador de interrupción) en el grupo de servicios antes de que el hardware empiece a generar interrupciones. Aunque el método Init genera un puntero de grupo de servicios al controlador de puerto, el controlador de puerto puede usar este puntero solo después de la devolución de Init.

En el caso de un controlador de puerto WavePci, el objeto port agrega su propio objeto IServiceSink al grupo de servicios que obtiene de la llamada IMiniportWavePci::NewStream . Cuando el ISR del controlador de miniporte llama posteriormente a Notificar para enviar notificaciones a ese grupo de servicios, el grupo de servicios pone en cola un DPC que reenvía la notificación al objeto IServiceSink del controlador de puerto, que a su vez hace lo siguiente:

  • Reenvía la notificación al flujo de minipuerto llamando al método de servicio IMiniportWavePciStream::Service.

  • Desencadena cualquier posición o evento de reloj en el pin que está listo para activarse.

La interfaz IServiceSink admite un único método:

IServiceSink::RequestService

La interfaz IServiceGroup admite los métodos siguientes:

IServiceGroup::AddMember

IServiceGroup::CancelDelayedService

IServiceGroup::RequestDelayedService

IServiceGroup::RemoveMember

IServiceGroup::SupportDelayedService

Además, el controlador del sistema PortCls proporciona una función PcNewServiceGroup para crear un nuevo objeto de grupo de servicios. Sin embargo, no existe ninguna función similar para crear un objeto receptor de servicio. El controlador de puerto simplemente agrega una interfaz IServiceSink a la implementación de su objeto de puerto principal, cuando se crea el objeto, por lo que es el receptor del servicio. El controlador de puerto puede agregar la interfaz IServiceSink del objeto de puerto al grupo de servicios que recibe del método Init o NewStream del controlador de miniporte. Para mayor comodidad, el archivo de encabezado Portcls.h define IMP_IServiceSink y IMP_IServiceGroup constantes para agregar interfaces IServiceSink e IServiceGroup a objetos de controlador.