Function sparking_lot_core::park
source · pub unsafe fn park(addr: *const (), expected: impl FnOnce() -> bool)
Expand description
Parks the current thread on addr
until notified,
but only if expected
returns true.
There are no spurious wake-ups (unlike std::thread::park
).
Safety
expected
can’t call any functions from thiscrate
, as this may cause deadlocks or panics.- Using addresses that you don’t own is highly discouraged.
This is because if multiple libraries/modules/anything
park
on the same address without knowledge of each other, it will cause something that from their perspective looks like spurious wake-ups, which is likely to break code, sincepark
guarantees that no spurious wake-ups will happen.
Notes
- The memory pointed to by
addr
isn’t written to, it isn’t read and no references to it are formed. expected
is called under a lock, which could block otherpark
,unpark_one
,unpark_some
orunpark_all
calls (even with differentaddr
). As such,expected
should return quickly.- This function ensures that if another thread does
something that would cause
expected
to return false and only then callsunpark_one
,unpark_some
orunpark_all
,park
will either be woken up or will not sleep.
Example
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
static WAKE_UP: AtomicBool = AtomicBool::new(false);
fn wait_for_event() {
//SAFETY: remember not to park on WAKE_UP in unrelated functions.
unsafe {
sparking_lot_core::park(&WAKE_UP as *const _ as *const _, || {
WAKE_UP.load(Relaxed) == false
})
}
}
fn notify_event_happened() {
//If these lines are reordered park may miss this notification
WAKE_UP.store(true, Relaxed);
sparking_lot_core::unpark_one(&WAKE_UP as *const _ as *const _)
}