แยกชุดข้อความย่อยในบทสนทนา

ระบบจะไม่บล็อกวิธีการที่ทำเครื่องหมายเป็น 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 จะช่วยให้การเรียกใช้บริการทั้งหมดทํางานตามลําดับความสําคัญและนโยบายการจัดตารางเวลาที่กําหนดไว้เป็นอย่างน้อย