Subprocesos del modelo

Los métodos marcados como oneway no se bloquean. Para los métodos no marcados como oneway, la llamada de método de un cliente se bloquea hasta que el servidor se completó la ejecución o se llamó a una devolución de llamada síncrona (lo que ocurra primero). Las implementaciones de métodos de servidor pueden llamar como máximo a una devolución de llamada síncrona; adicionales las llamadas de devolución de llamada se descartan y se registran como errores. Si se supone que un método devuelve valores a través de una devolución de llamada y no llama a su devolución de llamada, esto se registra como un y se informa como un error de transporte al cliente.

Subprocesos en modo de transferencia

En el modo de transferencia, la mayoría de las llamadas son síncronas. Sin embargo, para preservar el comportamiento previsto para que las llamadas de oneway no bloqueen al cliente, una para cada proceso. Para obtener más información, consulta la Descripción general de HIDL.

Subprocesos en HALs enlazadas

Para entregar llamadas RPC entrantes (incluidas devoluciones de llamada asíncronas de HALs a usuarios de HAL) y notificaciones de muerte, se asocia un conjunto de subprocesos a cada proceso que usa HIDL. Si un solo proceso implementa múltiples interfaces HIDL o de notificaciones de muerte, su grupo de subprocesos se comparte entre todos ellos. Cuándo Un proceso recibe una llamada de método entrante de un cliente y elige un subproceso libre. del conjunto de subprocesos y ejecuta la llamada en ese subproceso. Si no hay conversaciones libres disponible, se bloquea hasta que haya una disponible.

Si el servidor tiene un solo subproceso, se completan las llamadas al servidor. en orden. Un servidor con más de un subproceso podría completar las llamadas desordenadas. incluso si el cliente tiene un solo subproceso. Sin embargo, para un objeto de interfaz dado, Se garantiza que las llamadas de oneway estén ordenadas (consulta Modelo de subprocesos del servidor). Para un servidor multiproceso que aloja varias interfaces, llamadas oneway a diferentes interfaces pueden procesarse simultáneamente entre sí o con otras llamadas de bloqueo.

Se envían múltiples llamadas anidadas en el mismo subproceso de hwbinder. Por ejemplo: si un proceso (A) realiza una llamada síncrona de un subproceso de hwbinder al proceso (B), y, luego, el procesamiento (B) vuelve a llamar síncrona en el proceso (A), la llamada se ejecutado en el subproceso original de hwbinder en (A), que está bloqueado en el original llamada. Esta optimización permite tener un único servidor con subprocesos capaz de manejar llamadas anidadas, pero no se extiende a los casos en los que las llamadas se transmiten otra secuencia de llamadas de IPC. Por ejemplo, si el proceso (B) hubiera realizado una Llamada a Binder/vndbinder que llama a un proceso (C) y, luego, procesa (C) las llamadas de vuelta en (A), no se podrá publicar en el subproceso original en (A).

Modelo de subprocesos del servidor

Excepto por el modo de transferencia, las implementaciones del servidor de las interfaces HIDL están activas en un proceso diferente al del cliente y necesitas uno o más subprocesos esperando llamadas de método entrantes. Estos subprocesos son el conjunto de subprocesos del servidor; el servidor puede decide cuántos subprocesos quiere que se ejecuten en su conjunto de subprocesos y puede usar un subproceso de uno para serializar todas las llamadas en sus interfaces. Si el servidor tiene más de un subproceso en el conjunto de subprocesos, puede recibir mensajes entrantes de forma simultánea llamadas en cualquiera de sus interfaces (en C++, los datos compartidos deben ser trabada cuidadosamente).

Las llamadas unidireccionales a la misma interfaz se serializan. Si un sistema de autenticación de varios subprocesos El cliente llama a method1 y method2 en la interfaz. IFoo y method3 en la interfaz IBar, method1 y method2 siempre están serializados, pero method3 puede ejecutarse en paralelo con method1 y method2

Un solo subproceso de ejecución de cliente puede provocar una ejecución simultánea en un servidor con varios subprocesos de dos maneras:

  • No se bloquean las llamadas a oneway. Si una llamada a oneway es y, luego, se llama a un elemento que no es oneway, el servidor puede ejecutar la llamada a oneway y la que no es oneway al mismo tiempo.
  • Los métodos de servidor que pasan datos con devoluciones de llamada síncronas pueden desbloquear al cliente en cuanto se llama a la devolución de llamada desde el servidor.

Como alternativa, cualquier código en la función de servidor que se ejecute después de la devolución de llamada puede ejecutarse simultáneamente, y el servidor se encarga de las operaciones llamadas desde el cliente. Esto incluye el código en la función del servidor y las actualizaciones destructores que se ejecutan al final de la función. Si el servidor tiene más de un subproceso en su conjunto de subprocesos, los problemas de simultaneidad surgen incluso si llegan llamadas desde un solo subproceso de cliente. (Si alguna HAL entregada por un proceso necesita varios subprocesos, todas las HAL tienen varios subprocesos porque el conjunto de subprocesos compartidas por proceso).

Tan pronto como el servidor llama a la devolución de llamada proporcionada, el transporte puede llamar al implementar una devolución de llamada en el cliente y desbloquearlo. El cliente continúa en paralelo con lo que haga la implementación del servidor después de llamar al (que puede incluir destructores en ejecución). Código en la función de servidor después de que la devolución de llamada deje de bloquear al cliente (siempre y cuando el servidor threadpool tiene suficientes subprocesos para manejar llamadas entrantes), pero se puede ejecutar al mismo tiempo que las futuras llamadas del cliente (a menos que el subproceso del servidor solo un subproceso).

Además de las devoluciones de llamada síncronas, oneway llama desde un cliente de un solo subproceso puede ser manejado simultáneamente por un servidor con varios subprocesos en su conjunto de subprocesos, pero solo si esas llamadas a oneway se que se ejecutan en distintas interfaces. oneway llamada en el mismo siempre están serializados.

Nota: Recomendamos que las funciones del servidor realicen las siguientes acciones: devolver en cuanto haya llamado a la función de devolución de llamada.

Por ejemplo (en C++):

Return<void> someMethod(someMethod_cb _cb) {
    // Do some processing, then call callback with return data
    hidl_vec<uint32_t> vec = ...
    _cb(vec);
    // At this point, the client's callback is called,
    // and the client resumes execution.
    ...
    return Void(); // is basically a no-op
};

Modelo de subprocesos del cliente

El modelo de subprocesos en el cliente difiere entre las llamadas sin bloqueo (funciones marcadas con la palabra clave oneway) y el bloqueo llamadas (funciones que no tienen la palabra clave oneway especificada).

Bloquear llamadas

Para bloquear llamadas, el cliente lo bloquea hasta que ocurra una de las siguientes situaciones:

  • Se produce un error de transporte. el objeto Return contiene un error que se puede recuperar con Return::isOk().
  • La implementación del servidor llama a la devolución de llamada (si hubiera una).
  • La implementación del servidor muestra un valor (si no había ningún parámetro de devolución de llamada).

En caso de tener éxito, la función de devolución de llamada que el cliente pasa como argumento que siempre llama el servidor antes de que se devuelva la función. La devolución de llamada es ejecutado en el mismo subproceso en el que se realiza la llamada a la función. Por lo tanto, los implementadores debes tener cuidado al retener los bloqueos durante las llamadas a función (y evitarlos del todo si es posible). Una función sin una sentencia generates o una palabra clave oneway todavía se bloquea. que el cliente bloquea hasta que el servidor muestra un objeto Return<void>.

Llamadas unidireccionales

Cuando una función está marcada como oneway, el cliente muestra resultados de inmediato. y no espera a que el servidor complete su invocación de llamada a función. En el plataforma (y, en conjunto), significa que la llamada a función toma la mitad del tiempo porque ejecuta la mitad del código, pero cuando se escriben implementaciones que son sensibles al rendimiento, esto afecta la programación. Normalmente, utilizar una llamada unidireccional provoca que el emisor de la llamada continúe siendo programado, mientras que una llamada síncrona normal hace que el programador transfiera de inmediato del proceso del emisor al destinatario. Esta es una optimización de rendimiento Binder. Para servicios en los que la llamada unidireccional debe ejecutarse en el proceso de destino con una prioridad alta, se puede aplicar la política de programación del servicio receptor cambió. En C++, con el método de libhidltransport setMinSchedulerPolicy por las prioridades y políticas del programador definido en sched.h garantiza que todas las llamadas al servicio se ejecuten al al menos la política y la prioridad establecidas.