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 this crate, 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, since park 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 other park, unpark_one, unpark_some or unpark_all calls (even with different addr). 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 calls unpark_one, unpark_some or unpark_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 _)
}