ระบบจะไม่บล็อกวิธีการที่ทำเครื่องหมายเป็น oneway
สําหรับเมธอดที่ไม่ได้ทําเครื่องหมายเป็น oneway
การเรียกใช้เมธอดของไคลเอ็นต์จะบล็อกจนกว่าเซิร์ฟเวอร์จะดำเนินการเสร็จสิ้นหรือเรียกใช้การเรียกกลับแบบซิงค์ (ขึ้นอยู่กับว่ากรณีใดเกิดก่อน)
การใช้งานเมธอดเซิร์ฟเวอร์จะเรียกการเรียกกลับแบบซิงค์ได้สูงสุด 1 ครั้ง ระบบจะทิ้งการเรียกกลับเพิ่มเติมและบันทึกเป็นข้อผิดพลาด หากเมธอดหนึ่งควรจะแสดงผลค่าผ่านคอลแบ็ก แต่ไม่ได้เรียกคอลแบ็ก ระบบจะบันทึกเป็นข้อผิดพลาดและรายงานเป็นข้อผิดพลาดในการขนส่งไปยังไคลเอ็นต์
เทรดในโหมดส่งผ่าน
ในโหมดการส่งผ่าน การโทรส่วนใหญ่เป็นแบบซิงค์ อย่างไรก็ตาม ระบบจะสร้างเธรดสำหรับแต่ละกระบวนการเพื่อรักษาลักษณะการทำงานที่ต้องการซึ่งการเรียก oneway
จะไม่บล็อกไคลเอ็นต์ โปรดดูรายละเอียดที่หัวข้อภาพรวมของ HIDL
เทรดใน HAL แบบ Binderized
ระบบจะเชื่อมโยงพูลเธรดกับแต่ละกระบวนการที่ใช้ HIDL เพื่อให้บริการการเรียก RPC ที่เข้ามา (รวมถึงการเรียกกลับแบบแอซิงโครนัสจาก HAL ไปยังผู้ใช้ HAL) และการแจ้งเตือนการสิ้นสุด หากกระบวนการเดียวใช้อินเทอร์เฟซ HIDL และ/หรือตัวแฮนเดิลการแจ้งเตือนการสิ้นสุดการทำงานหลายรายการ ระบบจะแชร์พูลเธรดระหว่างกระบวนการทั้งหมด เมื่อกระบวนการได้รับการเรียกใช้เมธอดขาเข้าจากไคลเอ็นต์ ระบบจะเลือกเธรดว่างจากพูลเธรดและเรียกใช้เธรดนั้น หากไม่มีเธรดว่าง เทรดจะบล็อกจนกว่าจะมีเธรดว่าง
หากเซิร์ฟเวอร์มีเธรดเพียงเธรดเดียว การเรียกใช้เซิร์ฟเวอร์จะเสร็จสมบูรณ์ตามลําดับ เซิร์ฟเวอร์ที่มีเธรดมากกว่า 1 เธรดอาจโทรออกตามลำดับไม่ถูกต้องแม้ว่าไคลเอ็นต์จะมีเพียงเธรดเดียวก็ตาม อย่างไรก็ตาม สําหรับออบเจ็กต์อินเทอร์เฟซหนึ่งๆ ระบบจะรับประกันoneway
การเรียกใช้ตามลําดับ (ดูรูปแบบการแยกชุดข้อความของเซิร์ฟเวอร์) สําหรับเซิร์ฟเวอร์แบบหลายเธรดซึ่งโฮสต์อินเทอร์เฟซหลายรายการ oneway
การเรียกอินเทอร์เฟซต่างๆ อาจประมวลผลพร้อมกันกับอินเทอร์เฟซอื่นๆ หรือการเรียกอื่นๆ ที่บล็อก
ระบบจะส่งการเรียกที่ฝังไว้หลายรายการในเธรด hwbinder เดียวกัน ตัวอย่างเช่น หากกระบวนการ (ก) โทรติดต่อแบบซิงค์จากเธรด hwbinder ไปยังกระบวนการ (ข) แล้วกระบวนการ (ข) โทรติดต่อกลับแบบซิงค์ไปยังกระบวนการ (ก) การโทรจะดำเนินการในเธรด hwbinder เดิมใน (ก) ซึ่งถูกบล็อกในการโทรครั้งแรก การเพิ่มประสิทธิภาพนี้ช่วยให้เซิร์ฟเวอร์แบบเธรดเดียวสามารถจัดการการเรียกที่ฝังอยู่ได้ แต่จะใช้งานไม่ได้ในกรณีที่การเรียกดำเนินการผ่านลําดับการเรียก IPC อื่น เช่น หากกระบวนการ (ข) ทำการเรียกใช้ Binder/vndbinder ซึ่งเรียกใช้กระบวนการ (ค) แล้วกระบวนการ (ค) เรียกกลับไปยัง (ก) ระบบจะแสดงในเธรดเดิมของ (ก) ไม่ได้
รูปแบบการแยกชุดข้อความของเซิร์ฟเวอร์
ยกเว้นโหมดการส่งผ่าน การใช้งานอินเทอร์เฟซ HIDL ของเซิร์ฟเวอร์จะทำงานในกระบวนการอื่นที่แตกต่างจากไคลเอ็นต์ และต้องมีเธรดอย่างน้อย 1 รายการที่รอการเรียกเมธอดขาเข้า เทรดเหล่านี้คือ Threadpool ของเซิร์ฟเวอร์ โดยเซิร์ฟเวอร์จะตัดสินใจได้ว่าจะให้มีเทรดกี่รายการที่ทำงานใน Threadpool และสามารถใช้ Threadpool ขนาด 1 เพื่อจัดเรียงข้อมูลการเรียกทั้งหมดในอินเทอร์เฟซ หากเซิร์ฟเวอร์มีเธรดมากกว่า 1 เธรดใน Threadpool ก็จะรับการเรียกขาเข้าพร้อมกันบนอินเทอร์เฟซใดก็ได้ (ใน C++ หมายความว่าต้องล็อกข้อมูลที่แชร์อย่างระมัดระวัง)
การเรียกแบบ 1 ทิศทางไปยังอินเทอร์เฟซเดียวกันจะจัดเรียงตามลําดับ หากไคลเอ็นต์แบบหลายเธรดเรียก method1
และ method2
ในอินเทอร์เฟซ IFoo
และ method3
ในอินเทอร์เฟซ IBar
ระบบจะจัดเรียงตามลําดับ method1
และ method2
เสมอ แต่ method3
จะทํางานควบคู่ไปกับ method1
และ method2
ได้
การดำเนินการของเธรดไคลเอ็นต์รายการเดียวอาจทำให้เกิดการดำเนินการพร้อมกันบนเซิร์ฟเวอร์ที่มีเธรดหลายรายการได้ 2 วิธี ดังนี้
- บล็อกสายเรียกเข้าจาก
oneway
ไม่ได้ หากมีการเรียกใช้oneway
แล้วเรียกใช้รายการที่ไม่ใช่oneway
เซิร์ฟเวอร์จะเรียกใช้การเรียกใช้oneway
และการเรียกใช้รายการที่ไม่ใช่oneway
ได้พร้อมกัน - เมธอดเซิร์ฟเวอร์ที่ส่งข้อมูลกลับด้วยคอลแบ็กแบบซิงค์สามารถเลิกบล็อกไคลเอ็นต์ได้ทันทีที่มีคอลแบ็กเรียกจากเซิร์ฟเวอร์
สำหรับวิธีที่สอง โค้ดใดๆ ในฟังก์ชันเซิร์ฟเวอร์ที่ดำเนินการหลังจากเรียกใช้การเรียกกลับจะทํางานพร้อมกันได้ โดยเซิร์ฟเวอร์จะจัดการการเรียกใช้จากไคลเอ็นต์ในภายหลัง ซึ่งรวมถึงโค้ดในฟังก์ชันเซิร์ฟเวอร์และตัวทำลายอัตโนมัติที่ทำงานเมื่อสิ้นสุดฟังก์ชัน หากเซิร์ฟเวอร์มีเธรดมากกว่า 1 เธรดในพูลเธรด ปัญหาการเรียกใช้พร้อมกันจะปรากฏขึ้นแม้ว่าการเรียกจะมาจากเธรดไคลเอ็นต์เพียงเธรดเดียวก็ตาม (หาก HAL ที่ให้บริการโดยกระบวนการใดก็ตามต้องใช้หลายเธรด HAL ทั้งหมดจะมีหลายเธรดเนื่องจากมีการแชร์ Threadpool ต่อกระบวนการ)
ทันทีที่เซิร์ฟเวอร์เรียกคอลแบ็กที่ระบุไว้ ทรานสปอร์ตจะเรียกคอลแบ็กที่ติดตั้งใช้งานในไคลเอ็นต์และเลิกบล็อกไคลเอ็นต์ได้ ไคลเอ็นต์จะดําเนินการควบคู่ไปกับสิ่งที่การติดตั้งใช้งานเซิร์ฟเวอร์ทําหลังจากเรียกใช้การเรียกกลับ (ซึ่งอาจรวมถึงการเรียกใช้ตัวทำลาย) โค้ดในฟังก์ชันเซิร์ฟเวอร์หลังจากการเรียกกลับจะไม่บล็อกไคลเอ็นต์อีกต่อไป (ตราบใดที่กลุ่มเธรดเซิร์ฟเวอร์มีเธรดเพียงพอที่จะจัดการสายเรียกเข้า) แต่อาจทำงานพร้อมกันกับการเรียกจากไคลเอ็นต์ในอนาคต (เว้นแต่กลุ่มเธรดเซิร์ฟเวอร์จะมีเธรดเพียงเธรดเดียว)
นอกเหนือจากการเรียกกลับแบบซิงค์แล้ว เซิร์ฟเวอร์ที่มีหลายเธรดในพูลเธรดจะจัดการการเรียก oneway
จากไคลเอ็นต์แบบเธรดเดียวได้พร้อมกัน แต่จะดำเนินการได้ก็ต่อเมื่อการเรียก oneway
เหล่านั้นดำเนินการบนอินเทอร์เฟซที่แตกต่างกันเท่านั้น การเรียกใช้ oneway
ในอินเทอร์เฟซเดียวกันจะได้รับการซีเรียลไลซ์เสมอ
หมายเหตุ: เราขอแนะนําอย่างยิ่งให้ฟังก์ชันเซิร์ฟเวอร์แสดงผลลัพธ์ทันทีที่เรียกใช้ฟังก์ชัน Callback
เช่น (ใน 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 };
รูปแบบการแยกชุดข้อความของไคลเอ็นต์
รูปแบบการแยกชุดข้อความในไคลเอ็นต์จะแตกต่างกันระหว่างการเรียกแบบไม่บล็อก (ฟังก์ชันที่มีการทำเครื่องหมายด้วยคีย์เวิร์ด oneway
) และการเรียกแบบบล็อก (ฟังก์ชันที่ไม่ได้ระบุคีย์เวิร์ด oneway
)
บล็อกการโทร
สําหรับการบล็อกการโทร ลูกค้าจะบล็อกจนกว่าจะเกิดเหตุการณ์อย่างใดอย่างหนึ่งต่อไปนี้
- เกิดข้อผิดพลาดในการขนส่ง ออบเจ็กต์
Return
มีสถานะข้อผิดพลาดที่ดึงข้อมูลได้ด้วยReturn::isOk()
- การติดตั้งใช้งานเซิร์ฟเวอร์จะเรียกใช้การติดต่อกลับ (หากมี)
- การติดตั้งใช้งานเซิร์ฟเวอร์แสดงผลค่า (หากไม่มีพารามิเตอร์การเรียกกลับ)
ในกรณีที่ดำเนินการสำเร็จ เซิร์ฟเวอร์จะเรียกใช้ฟังก์ชัน Callback ที่ไคลเอ็นต์ส่งเป็นอาร์กิวเมนต์เสมอก่อนที่ฟังก์ชันจะแสดงผล ระบบจะเรียกใช้การเรียกกลับในเธรดเดียวกับที่มีการเรียกใช้ฟังก์ชัน ดังนั้นผู้ใช้งานจึงต้องระมัดระวังในการใช้ล็อกระหว่างการเรียกใช้ฟังก์ชัน (และหลีกเลี่ยงการใช้ล็อกโดยสิ้นเชิงหากเป็นไปได้) ฟังก์ชันที่ไม่มีคำสั่ง generates
หรือคีย์เวิร์ด oneway
จะยังคงบล็อกอยู่ โดยไคลเอ็นต์จะบล็อกจนกว่าเซิร์ฟเวอร์จะแสดงผลออบเจ็กต์ Return<void>
การโทรแบบทางเดียว
เมื่อทำเครื่องหมายฟังก์ชันเป็น oneway
แล้ว ไคลเอ็นต์จะแสดงผลทันทีและไม่รอให้เซิร์ฟเวอร์เรียกใช้การเรียกฟังก์ชันให้เสร็จสมบูรณ์ ในแง่ภาพรวม (และโดยรวม) หมายความว่าการเรียกใช้ฟังก์ชันจะใช้เวลาครึ่งหนึ่งเนื่องจากมีการดำเนินการโค้ดครึ่งหนึ่ง แต่เมื่อเขียนการใช้งานที่คำนึงถึงประสิทธิภาพ การดำเนินการนี้จะมีผลกระทบต่อการจัดตารางเวลา โดยปกติแล้ว การใช้การเรียกแบบทางเดียวจะทำให้ระบบกําหนดเวลาผู้เรียกต่อไป แต่การใช้การเรียกแบบซิงค์ตามปกติจะทำให้ตัวจัดตารางเวลาโอนจากกระบวนการของผู้เรียกไปยังกระบวนการของผู้รับทันที นี่เป็นการเพิ่มประสิทธิภาพในเครื่องมือจัดระเบียบ สําหรับบริการที่ต้องเรียกใช้การเรียกแบบ 1 ทิศทางในกระบวนการเป้าหมายที่มีลําดับความสําคัญสูง คุณสามารถเปลี่ยนนโยบายการกําหนดเวลาของบริการที่รับได้ ใน C++ การใช้เมธอดของ libhidltransport
setMinSchedulerPolicy
กับลําดับความสําคัญและนโยบายของเครื่องมือจัดตารางเวลาซึ่งระบุไว้ใน sched.h
จะช่วยให้การเรียกใช้บริการทั้งหมดทํางานตามลําดับความสําคัญและนโยบายการจัดตารางเวลาที่กําหนดไว้เป็นอย่างน้อย