Threading model

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