Metode yang ditandai sebagai oneway
tidak akan diblokir. Untuk metode yang tidak ditandai sebagai
oneway
, panggilan metode klien akan memblokir hingga server memiliki
telah selesai atau disebut callback sinkron (mana saja yang lebih dulu).
Implementasi metode server dapat memanggil maksimal satu callback sinkron; tambahan
panggilan callback akan dibuang dan dicatat dalam log sebagai error. Jika suatu metode seharusnya
nilai kembali melalui callback dan tidak memanggil callback-nya, hal ini dicatat dalam log sebagai
{i>error<i} dan dilaporkan sebagai
{i>error <i}transport ke klien.
Thread dalam mode passthrough
Dalam mode passthrough, sebagian besar panggilan dilakukan secara sinkron. Namun, untuk mempertahankan
perilaku yang diinginkan yang dipanggil oneway
tidak memblokir klien,
thread dibuat untuk setiap proses. Untuk mengetahui detailnya, lihat
Ringkasan HiDL.
Thread di HAL yang di-binder
Untuk menyalurkan panggilan RPC yang masuk (termasuk callback asinkron dari HAL ke pengguna HAL) dan notifikasi kematian, threadpool dikaitkan dengan setiap proses yang menggunakan HIDL. Jika satu proses mengimplementasikan beberapa antarmuka HIDL dan/atau pengendali notifikasi kematian, threadpool-nya dibagikan di antara mereka semua. Kapan sebuah proses menerima panggilan metode masuk dari klien, proses itu memilih thread bebas dari threadpool dan menjalankan panggilan pada thread tersebut. Jika tidak ada rangkaian pesan gratis yang tersedia, blok ini 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 yang tidak berurutan
meskipun klien hanya
memiliki satu thread. Namun, untuk objek antarmuka tertentu,
oneway
panggilan dijamin akan dipesan (lihat
Model threading server). Untuk server multi-thread yang
menghosting beberapa antarmuka, panggilan oneway
ke antarmuka yang berbeda
mungkin diproses secara bersamaan dengan
satu sama lain atau panggilan pemblokir lainnya.
Beberapa panggilan bertingkat dikirim pada thread hwbinder yang sama. Contohnya, jika sebuah proses (A) melakukan panggilan sinkron dari thread hwbinder ke proses (B), kemudian proses (B) membuat panggilan sinkron kembali ke proses (A), panggilan tersebut dieksekusi pada thread hwbinder asli di (A) yang diblokir pada panggilan telepon. Pengoptimalan ini memungkinkan untuk memiliki satu server thread yang dapat menangani panggilan bertingkat, tetapi tidak meluas hingga ke kasus yang melibatkan panggilan urutan lain dari panggilan IPC. Misalnya, jika proses (B) telah membuat panggilan binder/vndbinder yang memanggil proses (C) lalu panggilan proses (C) kembali ke (A), ia tidak dapat disajikan di thread asli di (A).
Model threading server
Kecuali untuk mode passthrough, implementasi server antarmuka HIDL secara live dalam proses yang berbeda dari klien dan membutuhkan satu atau beberapa thread yang menunggu panggilan metode masuk. Thread ini adalah kumpulan thread server; server itu dapat memutuskan berapa banyak thread yang ingin dijalankan di threadpool-nya, dan dapat menggunakan ukuran satu thread untuk menserialisasi semua panggilan pada antarmukanya. Jika server memiliki lebih dari satu thread di kumpulan thread, thread tersebut dapat menerima thread masuk panggilan di antarmukanya (di C++, ini berarti bahwa data yang dibagikan harus dikunci dengan hati-hati).
Panggilan satu arah ke antarmuka yang sama akan diserialisasi. Jika multi-thread
klien 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 klien eksekusi dapat menyebabkan eksekusi serentak pada server dengan beberapa thread dengan dua cara:
- Panggilan
oneway
tidak akan diblokir. Jika panggilanoneway
dieksekusi lalu non-oneway
dipanggil, server dapat mengeksekusi panggilanoneway
dan panggilan non-oneway
secara bersamaan. - Metode server yang meneruskan data kembali dengan callback sinkron dapat membuka blokir klien segera setelah callback dipanggil dari server.
Untuk cara kedua, semua kode dalam fungsi server yang dieksekusi setelah yang dipanggil dapat dieksekusi secara serentak, dengan server yang menangani panggilan dari klien. Hal ini mencakup kode dalam fungsi server dan destruktor yang dieksekusi di akhir fungsi. Jika server memiliki lebih dari satu thread di threadpool-nya, masalah konkurensi akan muncul meskipun panggilan datang hanya dari satu thread klien. (Jika ada HAL yang dilayani oleh suatu proses beberapa utas, semua HAL memiliki banyak utas karena kumpulan utas dibagikan per proses.)
Segera setelah server memanggil callback yang disediakan, transpor dapat memanggil metode mengimplementasikan callback pada klien dan membuka blokir klien. Klien melanjutkan secara paralel dengan apa pun yang dilakukan implementasi server setelah memanggil callback (yang mungkin termasuk menjalankan destruktor). Kode dalam fungsi server setelah callback tidak lagi memblokir klien (selama server threadpool memiliki cukup thread untuk menangani panggilan masuk), tetapi dapat dijalankan serentak dengan panggilan berikutnya dari klien (kecuali jika kumpulan thread server hanya satu thread).
Selain callback sinkron, oneway
memanggil dari
satu klien thread tunggal dapat ditangani
secara bersamaan oleh server dengan
thread di thread pool-nya, tetapi hanya jika panggilan oneway
tersebut
dieksekusi pada antarmuka
yang berbeda. oneway
panggilan di saluran yang sama
antarmuka selalu diserialisasi.
Catatan: Kami sangat menyarankan fungsi server untuk segera ditampilkan setelah fungsi callback dipanggil.
Misalnya (di 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-pemblokiran
(fungsi yang ditandai dengan kata kunci oneway
) dan pemblokiran
panggilan (fungsi yang tidak memiliki kata kunci oneway
yang ditetapkan).
Blokir panggilan
Untuk memblokir panggilan, klien melakukan pemblokiran hingga salah satu hal berikut terjadi:
- Terjadi error transportasi; objek
Return
berisi error status yang dapat diambil denganReturn::isOk()
. - Implementasi server akan memanggil callback (jika ada).
- Implementasi server akan menampilkan nilai (jika tidak ada parameter callback).
Jika berhasil, fungsi callback yang diteruskan klien sebagai argumen adalah
selalu dipanggil oleh server
sebelum fungsi itu sendiri kembali. Callback-nya adalah
dieksekusi pada thread yang sama dengan tempat panggilan fungsi dilakukan, sehingga pengimplementasi
harus berhati-hati saat memegang kunci selama panggilan fungsi (dan hindari memegangnya
sepenuhnya). Fungsi tanpa pernyataan generates
atau kata kunci oneway
masih memblokir; blok klien sampai
server akan menampilkan objek Return<void>
.
Panggilan satu arah
Saat fungsi ditandai sebagai oneway
, klien akan langsung ditampilkan
dan tidak menunggu server untuk
menyelesaikan pemanggilan fungsinya. Di
akan muncul (dan secara agregat), ini berarti panggilan fungsi mengambil setengah dari
waktu karena mengeksekusi setengah kode, tetapi saat menulis implementasi
sensitif terhadap kinerja, hal ini memiliki
implikasi pada penjadwalan. Biasanya,
menggunakan panggilan satu arah menyebabkan pemanggil terus dijadwalkan sedangkan
menggunakan panggilan sinkron normal menyebabkan
penjadwal untuk segera mentransfer
dari pemanggil ke
proses tujuan panggilan. Ini adalah pengoptimalan performa
{i>binder<i}. Untuk layanan yang panggilan satu arah harus dijalankan dalam proses target
dengan prioritas tinggi, kebijakan
penjadwalan layanan penerima dapat
ubah. Di C++, menggunakan metode libhidltransport
setMinSchedulerPolicy
dengan prioritas dan kebijakan penjadwal
yang ditentukan dalam sched.h
memastikan bahwa semua panggilan ke layanan berjalan dalam
setidaknya Anda memiliki prioritas dan
kebijakan penjadwalan yang ditetapkan.