Threading model

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 panggilan oneway dieksekusi lalu non-oneway dipanggil, server dapat mengeksekusi panggilan oneway 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 dengan Return::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.