פתרון המתנה וסגירה¶
המצב והתנאי הבאים מחליפים את המצב הפשוט בהרצאה. הקטע מצטרף לאותם טיפוסי סנכרון, ומציג את חלק הצרכן בתוך פונקציה שמחזיקה את הזוג המשותף.
struct State { result: Option<u64>, closed: bool }
fn receive(shared: &(Mutex<State>, Condvar)) -> Result<Option<u64>, &'static str> {
let state = shared.0.lock().map_err(|_| "poisoned")?;
let mut state = shared.1.wait_while(state, |s| s.result.is_none() && !s.closed)
.map_err(|_| "poisoned")?;
Ok(state.result.take())
}
הפעולה שסוגרת את המצב קובעת closed = true תחת אותה נעילה ואז קוראת notify_all. כך כל הממתינים יכולים לבדוק מחדש את התנאי. התראה ללא שינוי אינה גורמת להחזרת ערך, משום שהלולאה חוזרת להמתנה.
בדוגמת poison המדיניות היא להחזיר כשל ולא לחשוף מצב שלא אומת. אם בוחרים תיקון, צריך לכתוב מהו האינווריאנט, למשל סכום של שני מונים, ולבצע תיקון שניתן להצדיק מתוך הנתונים שנותרו. ניקוי הדגל לבדו אינו תיקון של המצב.