Métodos marcados como oneway
não são bloqueados. Para métodos não marcados como
oneway
, a chamada do método de um cliente fica bloqueada até que o servidor
concluída ou chamado de callback síncrono (o que ocorrer primeiro).
As implementações de método do servidor podem chamar no máximo um callback síncrono. extras
chamadas de callback são descartadas e registradas como erros. Se um método precisar
retorna valores por meio de callback e não invoca o callback, isso é registrado como
e relatado como um erro de transporte ao cliente.
Linhas de execução no modo de passagem
No modo de passagem, a maioria das chamadas é síncrona. No entanto, para preservar
comportamento pretendido que o método oneway
chama sem bloquear o cliente,
uma linha de execução é criada para cada processo. Para mais detalhes, consulte a
Visão geral do HIDL.
Linhas de execução em HALs vinculadas
Para atender a chamadas RPC recebidas (incluindo callbacks assíncronos de HALs para usuários da HAL) e notificações de interrupção, um grupo de linhas de execução é associado a cada processo que usa HIDL. Se um único processo implementar várias interfaces HIDL e/ou gerenciadores de notificações de morte, seu pool de linhas de execução será compartilhado entre todos eles. Quando um processo recebe uma chamada de método recebida de um cliente, ele escolhe uma linha de execução livre do pool de linhas de execução e executa a chamada nessa linha. Se nenhuma linha de execução livre for disponível, ele fica bloqueado até que um esteja disponível.
Se o servidor tiver apenas um thread, as chamadas para o servidor serão concluídas
em ordem. Um servidor com mais de um thread pode concluir chamadas fora de ordem
mesmo que o cliente tenha apenas um thread. No entanto, para um determinado objeto de interface,
As chamadas oneway
serão ordenadas corretamente. Consulte
modelo de linha de execução do servidor). Para um servidor com vários segmentos que
hospeda várias interfaces, oneway
chamadas para interfaces diferentes
podem ser processadas simultaneamente
umas às outras ou com outras chamadas de bloqueio.
Várias chamadas aninhadas são enviadas na mesma linha de execução hwbinder. Por exemplo: se um processo (A) faz uma chamada síncrona de uma linha de execução hwbinder para o processo (B), e depois o processo (B) faz uma chamada síncrona de volta ao processo (A), a chamada é executada na linha de execução hwbinder original em (A), que está bloqueada na a chamada. Essa otimização possibilita ter um único servidor de linha de execução capaz de lida com chamadas aninhadas, mas não se estende a casos em que as chamadas são transmitidas outra sequência de chamadas de IPC. Por exemplo, se o processo (B) tivesse feito chamada de vinculação/vndbinder que chamou um processo (C) e depois processa as chamadas (C) de volta em (A), ele não pode ser veiculado na linha de execução original em (A).
Modelo de linha de execução do servidor
Exceto para o modo de passagem, as implementações do servidor de interfaces HIDL estão ativas em um processo diferente daquele do cliente e precisam de uma ou mais linhas de execução esperando chamadas de método recebidas. Elas são o pool de linhas de execução do servidor. o servidor pode decide quantas linhas de execução quer executar no pool de linhas de execução e pode usar uma tamanho do pool de linhas de execução de um para serializar todas as chamadas nas interfaces. Se o servidor tiver mais de uma linha de execução no pool, ele poderá receber entradas simultâneas em qualquer uma de suas interfaces (em C++, isso significa que os dados compartilhados devem ser cuidadosamente).
As chamadas unidirecionais na mesma interface são serializadas. Se um cliente com várias linhas de execução
o cliente chama method1
e method2
na interface
IFoo
e method3
na interface IBar
method1
e method2
são sempre serializados, mas
method3
pode ser executado em paralelo com method1
e
method2
.
Um único thread do cliente pode causar uma execução simultânea em um com vários segmentos de duas maneiras:
- As chamadas
oneway
não são bloqueadas. Se uma chamadaoneway
for executado e um nãooneway
for chamado, o servidor poderá as chamadasoneway
e as que não sãooneway
ao mesmo tempo. - Os métodos de servidor que transmitem dados de volta com callbacks síncronos podem ser desbloqueados o cliente assim que a chamada de retorno for feita pelo servidor.
A segunda maneira, qualquer código na função do servidor que seja executado após a é chamado pode ser executado simultaneamente, com o servidor lidando com as do cliente. Isso inclui código na função de servidor e destruidores que são executados no final da função. Se o servidor tiver mais de uma linha de execução no pool de linhas de execução, surgem problemas de simultaneidade mesmo quando as chamadas estão em apenas uma conversa do cliente. Se alguma HAL veiculada por um processo precisar várias linhas de execução, todas as HALs têm várias linhas de execução, pois o conjunto de compartilhados por processo.
Assim que o servidor chamar o retorno de chamada fornecido, o transporte poderá chamar o método implementar o callback no cliente e desbloqueá-lo. O cliente prossegue em paralelo com o que a implementação do servidor fizer depois de chamar o método o que pode incluir a execução de destruidores. Código na função de servidor após o retorno de chamada não estar mais bloqueando o cliente (contanto que o servidor o pool de linhas de execução tem linhas de execução suficientes para processar chamadas recebidas), mas pode ser executado simultaneamente com futuras chamadas do cliente (a menos que o pool de linhas de execução do servidor tenha apenas um thread).
Além dos callbacks síncronos, oneway
chama de um
um cliente de thread único pode ser manipulado simultaneamente por um servidor com vários
linhas de execução no pool, mas somente se essas chamadas oneway
forem
executados em diferentes interfaces. oneway
chamadas ao mesmo
são sempre serializadas.
Observação: recomendamos que as funções de servidor retornar assim que chamarem a função de callback.
Por exemplo (em 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 linha de execução do cliente
O modelo de linha de execução no cliente é diferente entre chamadas sem bloqueio
(funções marcadas com a palavra-chave oneway
) e bloqueio
chamadas (funções que não têm a palavra-chave oneway
especificada).
Bloquear chamadas
Para o bloqueio de chamadas, o cliente bloqueia até que uma das seguintes situações aconteça:
- Ocorre um erro de transporte. o objeto
Return
contém um erro que pode ser recuperado comReturn::isOk()
. - A implementação do servidor chama o callback (se houver).
- A implementação do servidor retorna um valor (se não houver um parâmetro de callback).
Em caso de sucesso, a função de retorno de chamada que o cliente passa como um argumento é
sempre chamado pelo servidor antes do retorno da própria função. O callback é
executada na mesma linha de execução em que a chamada de função é feita. Assim, os implementadores
deve ter cuidado ao manter bloqueios durante chamadas de função (e evitá-los
completamente, quando possível). Uma função sem uma instrução generates
ou se uma palavra-chave oneway
ainda estiver bloqueando, que o cliente bloqueia até que
"server" retorna um objeto Return<void>
.
Chamadas unidirecionais
Quando uma função é marcada como oneway
, o cliente retorna imediatamente.
e não espera o servidor concluir a invocação da chamada de função. No
(e agregados), isso significa que a chamada da função ocupa metade da
tempo porque está executando metade do código, mas ao escrever implementações que
são sensíveis ao desempenho, isso tem algumas implicações na programação. Normalmente,
o uso de uma chamada unidirecional faz com que o autor da chamada continue a ser agendado, enquanto
o uso de uma chamada síncrona normal faz com que o programador transfira imediatamente
do autor da chamada para o processo do recebedor da chamada. Essa é uma otimização de desempenho
fichário. Para serviços em que a chamada unidirecional precisa ser executada no processo de destino
com alta prioridade, a política de agendamento do serviço receptor pode ser
mudou. Em C++, usando o método de libhidltransport
.
setMinSchedulerPolicy
com as prioridades e políticas do programador
definido em sched.h
garante que todas as chamadas para o serviço sejam executadas
pelo menos com a política e a prioridade definidas.