in src/sync/mutex.rs [153:188]
fn drop(&mut self) {
self.inner = None;
let mut state = self.mutex.state.borrow_mut();
trace!(waiters=?state.waiters, "releasing mutex {:p}", self.mutex);
state.holder = None;
// Bail out early if we're panicking so we don't try to touch `ExecutionState`
if ExecutionState::should_stop() {
return;
}
// Unblock every thread waiting on this lock. The scheduler will choose one of them to win
// the race to this lock, and that thread will re-block all the losers.
let me = ExecutionState::me();
state.holder = None;
for tid in state.waiters.iter() {
debug_assert_ne!(tid, me);
ExecutionState::with(|s| {
let t = s.get_mut(tid);
debug_assert!(t.blocked());
t.unblock();
});
}
// Update the Mutex clock with the releasing thread's clock
ExecutionState::with(|s| {
let clock = s.increment_clock();
state.clock.update(clock);
});
drop(state);
// Releasing a lock is a yield point
thread::switch();
}