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 aoneway
es y, luego, se llama a un elemento que no esoneway
, el servidor puede ejecutar la llamada aoneway
y la que no esoneway
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 conReturn::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,
una llamada unidireccional hace 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.