פתרון תורים שעונים ובעלות בחומרה¶
המודל מחזיר תשובה ריקה כשאין slot פנוי. הוא זורק כאשר קיבל תצפית שסותרת את החוזה, כי אין משמעות בטוחה להמשך המחזור במקרה כזה. את הבדיקות מוסיפים לפני סיום הmain.
bool backwards = false, future = false, bad_index = false;
try { ring.observe(2); } catch (const std::logic_error&) { backwards = true; }
try { ring.observe(99); } catch (const std::logic_error&) { future = true; }
try { (void)ring.submit(3); } catch (const std::out_of_range&) { bad_index = true; }
assert(backwards && future && bad_index);
החישוב של bytes הוא מספר המסגרות כפול nBlockAlign, עם בדיקת overflow אם מחשבים בגודל מוגבל. החישוב של זמן הוא מספר מסגרות חלקי sample rate. אף אחד מהם אינו כולל בהכרח את כל הpipeline, ולכן אין כאן מדידת סוף הדרך.
במסלול GPU הפתרון ממפה כל allocation לערך fence שמוצב אחרי השימוש האחרון בו. כאשר כמה queues משתמשים באותו משאב צריך קשר השלמה לכל המשתמשים או סנכרון מפורש ביניהם. החזרה של fence יחיד אינה מספיקה אם queue נוסף עדיין קורא את הנתונים.
במסלול אודיו קוראים את הקיבולת ואת padding לפי סוג הstream, מבקשים רק מספר frames זמין ומשחררים את הbuffer לפי חוזה IAudioRenderClient. מסלול השקט משתמש בדגל silent ואינו מניח שכל פורמט מייצג שקט באותה כתיבה שרירותית. הכשל של endpoint invalidation מעביר את הstream למצב סיום ויצירה מחדש, בלי להשתמש בclient הישן כאילו הוא עדיין מחובר.
במסלול HID מתעדים עבור כל בקשה מי מחזיק את הOVERLAPPED ואת הbuffer. בקשת cancel אינה מאפשרת לשחרר אותם לפני ההשלמה הסופית. ניתוק ושגיאת completion הם נתונים בפרוטוקול החיים של ההתקן, ולא חריגה שמצדיקה לדלג על cleanup.
הפתרון המלא של ההתמחות כולל את הקוד של התחום שנבחר ואת תוצאות המעבדה שלו. שלוש ההתמחויות אינן אותה תוכנית, ולכן אין טעם להמציא wrapper שמסתיר את ההבדלים החשובים ביניהן.