روشهایی که بهعنوان oneway
علامتگذاری شدهاند، مسدود نمیشوند. برای روشهایی که بهعنوان oneway
علامتگذاری نشدهاند، فراخوانی روش مشتری مسدود میشود تا زمانی که سرور اجرا را کامل کند یا یک تماس همگام را فراخوانی کند (هر کدام که اول باشد). پیاده سازی روش سرور حداکثر می تواند یک تماس همزمان همزمان را فراخوانی کند. تماس های برگشتی اضافی کنار گذاشته می شوند و به عنوان خطا ثبت می شوند. اگر قرار باشد متدی مقادیر را از طریق callback برگرداند و پاسخ تماس خود را فراخوانی نکند، این به عنوان یک خطا ثبت می شود و به عنوان یک خطای انتقال به مشتری گزارش می شود.
موضوعات در حالت عبور
در حالت عبور، بیشتر تماس ها همزمان هستند. با این حال، برای حفظ رفتار مورد نظر که تماس های oneway
مشتری را مسدود نمی کند، یک رشته برای هر فرآیند ایجاد می شود. برای جزئیات، به نمای کلی HIDL مراجعه کنید.
نخ ها در HAL های بایندر شده
برای ارائه تماسهای ورودی RPC (از جمله تماسهای ناهمزمان از HAL به کاربران HAL) و اعلانهای مرگ، یک Threadpool با هر فرآیندی که از HIDL استفاده میکند مرتبط است. اگر یک فرآیند واحد، چندین رابط HIDL و/یا کنترل کننده های اعلان مرگ را پیاده سازی کند، Threadpool آن بین همه آنها به اشتراک گذاشته می شود. هنگامی که یک فرآیند یک فراخوانی متد دریافتی از یک کلاینت دریافت می کند، یک رشته آزاد را از threadpool انتخاب می کند و تماس را روی آن رشته اجرا می کند. اگر رشته رایگان در دسترس نباشد، تا زمانی که یکی در دسترس نباشد مسدود می شود.
اگر سرور فقط یک رشته داشته باشد، فراخوانی به سرور به ترتیب تکمیل می شود. سروری با بیش از یک رشته ممکن است تماسهای بدون نظم را تکمیل کند حتی اگر مشتری فقط یک رشته داشته باشد. با این حال، برای یک شی رابط معین، تماس های oneway
تضمین شده است که سفارش داده شوند (به مدل threading سرور مراجعه کنید). برای یک سرور چند رشته ای که چندین رابط را میزبانی می کند، تماس های oneway
به رابط های مختلف ممکن است همزمان با یکدیگر یا سایر تماس های مسدود کننده پردازش شوند.
چندین تماس تو در تو در یک رشته hwbinder ارسال می شود. به عنوان مثال، اگر یک فرآیند (A) یک فراخوانی همزمان از یک رشته hwbinder به فرآیند (B) برقرار کند، و سپس فرآیند (B) یک فراخوانی همزمان به فرآیند (A) برقرار کند، این فراخوانی بر روی رشته hwbinder اصلی در (الف) که در تماس اصلی مسدود شده است. این بهینهسازی این امکان را فراهم میکند که یک سرور رشتهای واحد داشته باشیم که بتواند تماسهای تودرتو را مدیریت کند، اما به مواردی که تماسها از طریق دنبالهای دیگر از تماسهای IPC منتقل میشوند، گسترش نمییابد. به عنوان مثال، اگر فرآیند (B) یک فراخوانی binder/vndbinder ایجاد کرده باشد که به یک فرآیند (C) فراخوانی میکند و سپس پردازش (C) به (A) باز میگردد، نمیتوان آن را روی رشته اصلی در (A) ارائه کرد. .
مدل threading سرور
به جز حالت عبور، پیادهسازیهای سرور رابطهای HIDL در فرآیندی متفاوت از کلاینت زندگی میکنند و به یک یا چند رشته در انتظار تماسهای متد ورودی نیاز دارند. این رشته ها Threadpool سرور هستند. سرور می تواند تصمیم بگیرد که چه تعداد رشته می خواهد در threadpool خود اجرا شود و می تواند از یک Threadpool اندازه یک برای سریال کردن همه تماس ها در رابط های خود استفاده کند. اگر سرور بیش از یک رشته در threadpool داشته باشد، میتواند تماسهای ورودی همزمان را در هر یک از رابطهای خود دریافت کند (در C++، این بدان معناست که دادههای مشترک باید با دقت قفل شوند).
تماس های یک طرفه به یک رابط یکسان سریالی می شوند. اگر یک کلاینت چند رشته ای method1
و method2
را در واسط IFoo
و method3
در واسط IBar
فراخوانی کند، method1
و method2
همیشه سریالی هستند، اما method3
می تواند به موازات method1
و method2
اجرا شود.
یک رشته اجرای کلاینت به دو صورت می تواند باعث اجرای همزمان روی سروری با رشته های متعدد شود:
- تماس های
oneway
مسدود نمی شوند. اگر یک تماسoneway
اجرا شود و سپس یک غیرoneway
فراخوانی شود، سرور می تواند تماسoneway
و تماس غیرoneway
را به طور همزمان اجرا کند. - روشهای سروری که دادهها را با تماسهای همگام ارسال میکنند، میتوانند به محض فراخوانی تماس از سرور، کلاینت را رفع انسداد کنند.
برای راه دوم، هر کدی در تابع سرور که پس از فراخوانی تماس مجدد اجرا میشود، میتواند همزمان اجرا شود و سرور تماسهای بعدی مشتری را مدیریت میکند. این شامل کد در عملکرد سرور و تخریب کننده های خودکار است که در پایان عملکرد اجرا می شوند. اگر سرور بیش از یک رشته در threadpool خود داشته باشد، مشکلات همزمانی ایجاد میشود حتی اگر تماسها فقط از یک رشته مشتری منفرد وارد شوند. (اگر هر HAL ارائه شده توسط یک فرآیند به چندین رشته نیاز داشته باشد، همه HAL ها دارای چندین رشته هستند زیرا threadpool در هر فرآیند به اشتراک گذاشته می شود.)
به محض اینکه سرور تماس ارائه شده را فراخوانی می کند، حمل و نقل می تواند callback پیاده سازی شده را روی کلاینت فراخوانی کرده و کلاینت را رفع انسداد کند. کلاینت به موازات هر کاری که اجرای سرور انجام می دهد، پس از فراخوانی تماس (که ممکن است شامل تخریب کننده های در حال اجرا باشد) پیش می رود. کد در عملکرد سرور پس از پاسخ به تماس دیگر کلاینت را مسدود نمی کند (تا زمانی که threadpool سرور رشته های کافی برای رسیدگی به تماس های دریافتی داشته باشد)، اما ممکن است همزمان با تماس های آینده از مشتری اجرا شود (مگر اینکه threadpool سرور فقط یک رشته داشته باشد. ).
علاوه بر تماسهای همزمان، تماسهای oneway
از یک کلاینت تک رشتهای را میتوان بهطور همزمان توسط سروری با رشتههای متعدد در threadpool آن مدیریت کرد، اما تنها در صورتی که آن تماسهای oneway
در رابطهای مختلف اجرا شوند. تماس های oneway
روی یک رابط همیشه سریالی هستند.
توجه: ما قویاً توابع سرور را تشویق میکنیم که به محض فراخوانی تابع تماس مجدد برگردند.
به عنوان مثال (در 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 };
مدل threading مشتری
مدل threading روی کلاینت بین تماسهای غیر مسدود (عملکردهایی که با کلمه کلیدی oneway
مشخص شدهاند) و تماسهای مسدودکننده (عملکردهایی که کلمه کلیدی oneway
مشخص شده ندارند) متفاوت است.
مسدود کردن تماس ها
برای مسدود کردن تماس ها، مشتری مسدود می شود تا زمانی که یکی از موارد زیر رخ دهد:
- خطای حمل و نقل رخ می دهد. شی
Return
حاوی یک حالت خطا است که باReturn::isOk()
قابل بازیابی است. - پیاده سازی سرور، تماس برگشتی را فراخوانی می کند (در صورت وجود).
- اجرای سرور یک مقدار را برمی گرداند (اگر هیچ پارامتر برگشتی وجود نداشته باشد).
در صورت موفقیت، تابع callback که کلاینت به عنوان آرگومان ارسال می کند، همیشه قبل از بازگشت خود تابع توسط سرور فراخوانی می شود. فراخوانی بر روی همان رشتهای اجرا میشود که فراخوانی تابع روی آن انجام میشود، بنابراین پیادهکنندهها باید مراقب نگه داشتن قفلها در طول فراخوانی تابع باشند (و در صورت امکان از آنها بهکلی اجتناب کنند). یک تابع بدون دستور generates
یا کلمه کلیدی oneway
همچنان مسدود است. تا زمانی که سرور یک شی Return<void>
را برگرداند، کلاینت مسدود می شود.
تماس های یک طرفه
هنگامی که یک تابع oneway
علامت گذاری می شود، مشتری بلافاصله برمی گردد و منتظر نمی ماند تا سرور فراخوانی تابع خود را تکمیل کند. در سطح (و در مجموع)، این بدان معنی است که فراخوانی تابع نیمی از زمان را می گیرد زیرا نیمی از کد را اجرا می کند، اما هنگام نوشتن پیاده سازی هایی که به عملکرد حساس هستند، این امر دارای برخی مفاهیم زمان بندی است. به طور معمول، استفاده از تماس یک طرفه باعث میشود که تماسگیرنده به زمانبندی ادامه دهد، در حالی که استفاده از تماس معمولی همزمان باعث میشود که زمانبندی بلافاصله از تماسگیرنده به فرآیند تماس گیرنده منتقل شود. این یک بهینه سازی عملکرد در کلاسور است. برای سرویس هایی که تماس یک طرفه باید در فرآیند هدف با اولویت بالا اجرا شود، می توان خط مشی زمان بندی سرویس گیرنده را تغییر داد. در C++، با استفاده از روش libhidltransport
setMinSchedulerPolicy
با اولویتهای زمانبندی و سیاستهای تعریفشده در sched.h
تضمین میکند که همه تماسها به سرویس حداقل در خطمشی زمانبندی تنظیم شده و اولویت اجرا میشوند.