Metode yang ditandai sebagai oneway
tidak memblokir. Untuk metode yang tidak ditandai sebagai
oneway
, panggilan metode klien akan diblokir hingga server telah
menyelesaikan eksekusi atau memanggil callback sinkron (mana saja yang lebih dulu).
Implementasi metode server dapat memanggil maksimal satu callback sinkron; panggilan callback tambahan akan dihapus dan dicatat sebagai error. Jika metode seharusnya
menampilkan nilai melalui callback dan tidak memanggil callback-nya, hal ini akan dicatat ke dalam log sebagai
error dan dilaporkan sebagai error transpor ke klien.
Thread dalam mode passthrough
Dalam mode passthrough, sebagian besar panggilan bersifat sinkron. Namun, untuk mempertahankan
perilaku yang diinginkan agar panggilan oneway
tidak memblokir klien, thread dibuat untuk setiap proses. Untuk mengetahui detailnya, lihat
ringkasan HIDL.
Thread dalam HAL binderized
Untuk menayangkan panggilan RPC yang masuk (termasuk callback asinkron dari HAL ke pengguna HAL) dan notifikasi penghentian, threadpool dikaitkan dengan setiap proses yang menggunakan HIDL. Jika satu proses menerapkan beberapa antarmuka HIDL dan/atau pengelola notifikasi kematian, threadpool-nya akan dibagikan di antara semuanya. Saat proses menerima panggilan metode masuk dari klien, proses tersebut akan memilih thread gratis dari threadpool dan menjalankan panggilan pada thread tersebut. Jika tidak ada thread gratis yang tersedia, thread akan diblokir hingga tersedia.
Jika server hanya memiliki satu thread, panggilan ke server akan diselesaikan
secara berurutan. Server dengan lebih dari satu thread mungkin menyelesaikan panggilan secara tidak berurutan
meskipun klien hanya memiliki satu thread. Namun, untuk objek antarmuka tertentu,
panggilan oneway
dijamin akan diurutkan (lihat
Model threading server). Untuk server multi-thread yang
menghosting beberapa antarmuka, panggilan oneway
ke antarmuka yang berbeda
mungkin diproses secara serentak dengan satu sama lain atau panggilan pemblokiran lainnya.
Beberapa panggilan bertingkat dikirim di thread hwbinder yang sama. Misalnya, jika proses (A) melakukan panggilan sinkron dari thread hwbinder ke proses (B), lalu proses (B) melakukan panggilan sinkron kembali ke proses (A), panggilan tersebut dijalankan pada thread hwbinder asli di (A) yang diblokir pada panggilan asli. Pengoptimalan ini memungkinkan server dengan satu thread dapat menangani panggilan bertingkat, tetapi tidak diperluas ke kasus saat panggilan berjalan melalui urutan panggilan IPC lainnya. Misalnya, jika proses (B) telah membuat panggilan binder/vndbinder yang memanggil proses (C), lalu proses (C) memanggil kembali ke (A), proses tersebut tidak dapat ditayangkan di thread asli di (A).
Model threading server
Kecuali untuk mode passthrough, implementasi server antarmuka HIDL berada dalam proses yang berbeda dengan klien dan memerlukan satu atau beberapa thread yang menunggu panggilan metode masuk. Thread ini adalah threadpool server; server dapat menentukan jumlah thread yang ingin dijalankan di threadpool-nya, dan dapat menggunakan ukuran threadpool satu untuk melakukan serialisasi semua panggilan di antarmukanya. Jika server memiliki lebih dari satu thread di threadpool, server dapat menerima panggilan masuk serentak di antarmuka mana pun (di C++, ini berarti data bersama harus dikunci dengan cermat).
Panggilan satu arah ke antarmuka yang sama akan diserialisasi. Jika klien multi-thread
memanggil method1
dan method2
pada antarmuka
IFoo
, dan method3
pada antarmuka IBar
,
method1
dan method2
selalu diserialisasi, tetapi
method3
dapat berjalan secara paralel dengan method1
dan
method2
.
Satu thread eksekusi klien dapat menyebabkan eksekusi serentak di server dengan beberapa thread dengan dua cara:
- Panggilan
oneway
tidak diblokir. Jika panggilanoneway
dijalankan, lalu non-oneway
dipanggil, server dapat menjalankan panggilanoneway
dan panggilan non-oneway
secara bersamaan. - Metode server yang meneruskan data kembali dengan callback sinkron dapat membatalkan pemblokiran klien segera setelah callback dipanggil dari server.
Untuk cara kedua, kode apa pun dalam fungsi server yang dieksekusi setelah callback dipanggil dapat dieksekusi secara serentak, dengan server menangani panggilan berikutnya dari klien. Ini mencakup kode dalam fungsi server dan destruktor otomatis yang dieksekusi di akhir fungsi. Jika server memiliki lebih dari satu thread dalam threadpool-nya, masalah konkurensi akan muncul meskipun panggilan hanya berasal dari satu thread klien. (Jika HAL yang ditayangkan oleh proses memerlukan beberapa thread, semua HAL memiliki beberapa thread karena threadpool dibagikan per proses.)
Segera setelah server memanggil callback yang disediakan, transpor dapat memanggil callback yang diterapkan di klien dan berhenti memblokir klien. Klien melanjutkan secara paralel dengan apa pun yang dilakukan implementasi server setelah memanggil callback (yang mungkin mencakup penghancur yang berjalan). Kode dalam fungsi server setelah callback tidak lagi memblokir klien (selama threadpool server memiliki cukup thread untuk menangani panggilan masuk), tetapi dapat dijalankan secara serentak dengan panggilan mendatang dari klien (kecuali jika threadpool server hanya memiliki satu thread).
Selain callback sinkron, panggilan oneway
dari
klien dengan thread tunggal dapat ditangani secara serentak oleh server dengan beberapa
thread dalam threadpool-nya, tetapi hanya jika panggilan oneway
tersebut
dijalankan di antarmuka yang berbeda. Panggilan oneway
pada antarmuka
yang sama selalu diserialisasi.
Catatan: Sebaiknya fungsi server kembali segera setelah memanggil fungsi callback.
Misalnya (dalam 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 };
Model threading klien
Model threading pada klien berbeda antara panggilan non-blocking (fungsi yang ditandai dengan kata kunci oneway
) dan panggilan pemblokiran (fungsi yang tidak memiliki kata kunci oneway
yang ditentukan).
Blokir panggilan
Untuk memblokir panggilan, klien akan memblokir hingga salah satu hal berikut terjadi:
- Terjadi error transpor; objek
Return
berisi status error yang dapat diambil denganReturn::isOk()
. - Implementasi server memanggil callback (jika ada).
- Implementasi server menampilkan nilai (jika tidak ada parameter callback).
Jika berhasil, fungsi callback yang diteruskan klien sebagai argumen
selalu dipanggil oleh server sebelum fungsi itu sendiri ditampilkan. Callback
dijalankan pada thread yang sama dengan tempat panggilan fungsi dibuat, sehingga implementator
harus berhati-hati dengan memegang kunci selama panggilan fungsi (dan menghindarinya
sepenuhnya jika memungkinkan). Fungsi tanpa pernyataan generates
atau kata kunci oneway
masih memblokir; klien memblokir hingga
server menampilkan objek Return<void>
.
Panggilan satu arah
Saat fungsi ditandai oneway
, klien akan segera ditampilkan
dan tidak menunggu server menyelesaikan pemanggilan panggilan fungsinya. Pada
permukaan (dan secara agregat), ini berarti panggilan fungsi memerlukan setengah
waktu karena menjalankan setengah kode, tetapi saat menulis implementasi yang
sensitif terhadap performa, hal ini memiliki beberapa implikasi penjadwalan. Biasanya,
menggunakan panggilan satu arah menyebabkan pemanggil terus dijadwalkan, sedangkan
menggunakan panggilan sinkron normal menyebabkan penjadwal segera mentransfer
dari pemanggil ke proses yang dipanggil. Ini adalah pengoptimalan performa di
binder. Untuk layanan yang panggilan satu arahnya harus dijalankan dalam proses target
dengan prioritas tinggi, kebijakan penjadwalan layanan penerima dapat
diubah. Di C++, menggunakan metode libhidltransport
setMinSchedulerPolicy
dengan prioritas dan kebijakan penjadwal
yang ditentukan di sched.h
memastikan bahwa semua panggilan ke layanan berjalan setidaknya
pada kebijakan dan prioritas penjadwalan yang ditetapkan.