مدل های نخ زنی

روش هایی که به عنوان oneway علامت گذاری شده اند مسدود نمی شوند. برای روش‌هایی که به‌عنوان oneway علامت‌گذاری نشده‌اند، فراخوانی روش کلاینت تا زمانی که سرور اجرا را کامل کند یا یک تماس همگام را فراخوانی کند (هر کدام که اول باشد) مسدود می‌شود. پیاده سازی روش سرور ممکن است حداکثر یک تماس همزمان را فراخوانی کند. تماس های برگشتی اضافی کنار گذاشته می شوند و به عنوان خطا ثبت می شوند. اگر قرار باشد متدی مقادیری را از طریق callback برگرداند و پاسخ تماس خود را فراخوانی نکند، این به عنوان یک خطا ثبت می شود و به عنوان یک خطای انتقال به مشتری گزارش می شود.

موضوعات در حالت عبور

در حالت عبور، بیشتر تماس ها همزمان هستند. با این حال، برای حفظ رفتار مورد نظر که فراخوانی های oneway مشتری را مسدود نمی کند، یک رشته برای هر فرآیند ایجاد می شود. برای جزئیات، به نمای کلی HIDL مراجعه کنید.

نخ ها در HAL های بایندر شده

برای ارائه تماس‌های ورودی RPC (از جمله تماس‌های ناهمزمان از HAL به کاربران HAL) و اعلان‌های مرگ، یک Threadpool با هر فرآیندی که از HIDL استفاده می‌کند مرتبط است. اگر یک فرآیند واحد، چندین رابط HIDL و/یا کنترل کننده های اعلان مرگ را پیاده سازی کند، Threadpool آن بین همه آنها به اشتراک گذاشته می شود. هنگامی که یک فرآیند یک فراخوانی متد دریافتی از یک کلاینت دریافت می کند، یک رشته آزاد را از threadpool انتخاب می کند و تماس را روی آن رشته اجرا می کند. اگر رشته رایگان در دسترس نباشد، تا زمانی که یکی در دسترس نباشد مسدود می شود.

اگر سرور فقط یک رشته داشته باشد، فراخوانی به سرور به ترتیب تکمیل می شود. سروری با بیش از یک رشته ممکن است تماس‌های بدون نظم را تکمیل کند حتی اگر مشتری فقط یک رشته داشته باشد. با این حال، برای یک شی رابط معین، تماس های oneway تضمین شده است که سفارش داده شوند (به مدل threading سرور مراجعه کنید). برای یک سرور چند رشته ای که چندین رابط را میزبانی می کند، تماس های oneway به رابط های مختلف ممکن است همزمان با یکدیگر یا سایر تماس های مسدود کننده پردازش شوند.

چند تماس تو در تو در همان رشته hwbinder ارسال می شود. به عنوان مثال، اگر یک فرآیند (A) یک فراخوانی همزمان از یک رشته hwbinder به فرآیند (B) و سپس پردازش (B) یک فراخوانی همزمان به فرآیند (A) برقرار کند، این فراخوانی روی رشته اصلی hwbinder اجرا می‌شود. در (A) که در تماس اصلی مسدود شده است. این بهینه‌سازی این امکان را فراهم می‌کند که یک سرور رشته‌ای واحد داشته باشیم که بتواند تماس‌های تودرتو را مدیریت کند، اما به مواردی که تماس‌ها از طریق دنباله دیگری از تماس‌های 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 will be called,
    // and the client will resume 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 تضمین می‌کند که همه تماس‌ها به سرویس حداقل در خط‌مشی زمان‌بندی تنظیم شده و اولویت اجرا می‌شوند.