פתרון מאגרי תהליכונים וסביבות משתמש¶
כאשר cleanup אינו מבטל callbacks ממתינים, חמש ההגשות ל־work צריכות להגיע לסיום לפני החזרה מהניקוי, בהנחה שלא הייתה תקלה חיצונית בתהליך. ה־timer תלוי בהגעת זמן ובתזמון, ולכן מספרו אינו קבוע לפי מספר המילישניות בלבד.
עם TRUE, עבודה שעדיין לא התחילה יכולה להתבטל. עבודה שכבר התחילה אינה נעצרת באמצע על ידי הדגל; הניקוי ממתין לה. לכן אי אפשר להשתמש בדגל כתחליף לביטול שיתופי של callback ארוך.
הסדר של producer תקין הוא עצירת מקורות ההגשה, join או אישור סיום שלהם, עצירת timers ואז drain של callbacks. אם כמה threads יכולים להגיש, כולם צריכים להשתתף באותו פרוטוקול. בדיקת bool בלי סנכרון אינה מספיקה.
אפשר לבדוק session באמצעות התוכנית הקצרה הבאה. היא אינה משנה את הסביבה.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <cstdio>
int main() {
DWORD session = 0;
if (!ProcessIdToSessionId(GetCurrentProcessId(), &session)) {
std::printf("error=%lu\n", GetLastError());
return 1;
}
std::printf("pid=%lu session=%lu\n", GetCurrentProcessId(), session);
}
ה־cleanup group משחררת את אובייקטי העבודה והטיימר שאליהם היא קשורה. פעולת close נוספת עליהם תהיה שימוש במצב שכבר שוחרר. לאחר מכן משמידים את סביבת ה־callback, סוגרים את הקבוצה ואת המאגר לפי הסדר שנבחר.
ה־Context עדיין חי כשכל הפעולות האלה מתבצעות. זהו האינווריאנט שמאפשר ל־callbacks לגשת למונים. שינוי סוג המונה ל־atomic אינו היה מתקן context שכבר הושמד.
ה־SessionId מתאר הקשר של התהליך. הוספת עובדים אינה הופכת אותו לתהליך אינטראקטיבי ואינה נותנת לו הרשאות אחרות. הפרדה כזו תדרוש ארכיטקטורה עם רכיב משתמש מתאים וערוץ תקשורת, כפי שנבנה בהמשך.