Parker: park with callback before waiting

This commit is contained in:
Janis 2025-07-05 14:21:31 +02:00
parent c9e69c3b06
commit 4c70dbfc71

View file

@ -214,11 +214,38 @@ impl Parker {
}
pub fn park(&self) {
self.park_inner(|| ());
}
pub fn park_with_callback<F>(&self, before_sleep: F)
where
F: FnOnce(),
{
// This function is called when the thread is about to park.
self.park_inner(before_sleep);
}
// If the caller wants to park the thread on a mutex'd condition, it is
// possible for a deadlock to occur when the mutex is dropped just before
// this parker atomically changes it's state to `PARKED`. For that reason,
// we use a callback to allow the caller to perform any necessary actions
// before parking, but after the parker is set to `PARKED`. If another
// thread then checks the condition and checks if this thread should be
// woken, we will be immediately notified.
// Thusly, it is important that any caller synchronise any conditionals with
// a mutex externally, and then unlock that mutex in `before_sleep`.
fn park_inner<F>(&self, before_sleep: F)
where
F: FnOnce(),
{
if self.mutex.fetch_sub(1, Ordering::Acquire) == Self::NOTIFIED {
before_sleep();
// The thread was notified, so we can return immediately.
return;
}
before_sleep();
loop {
atomic_wait::wait(&self.mutex, Self::PARKED);