Skip to content

Instantly share code, notes, and snippets.

@cr0sh
Created January 24, 2025 11:33
Show Gist options
  • Select an option

  • Save cr0sh/e5408a5d74366ae44bf1b19edc252363 to your computer and use it in GitHub Desktop.

Select an option

Save cr0sh/e5408a5d74366ae44bf1b19edc252363 to your computer and use it in GitHub Desktop.
Rust std LazyLock ported to parking-lot
mod lazy_lock {
use parking_lot::{Once, OnceState};
use std::{cell::UnsafeCell, default::Default, mem::ManuallyDrop, ops::Deref};
union Data<T, F> {
value: ManuallyDrop<T>,
f: ManuallyDrop<F>,
}
pub struct LazyLock<T, F = fn() -> T> {
once: Once,
data: UnsafeCell<Data<T, F>>,
}
impl<T: Default> Default for LazyLock<T> {
fn default() -> Self {
Self::new(Default::default)
}
}
impl<T, F: FnOnce() -> T> LazyLock<T, F> {
/// Creates a new lazy value. with the given initializing function.
#[inline]
pub const fn new(f: F) -> LazyLock<T, F> {
LazyLock {
once: Once::new(),
data: UnsafeCell::new(Data {
f: ManuallyDrop::new(f),
}),
}
}
/// Returns a reference to the value if initialized, or `None` if not.
#[inline]
pub fn get(this: &LazyLock<T, F>) -> Option<&T> {
if this.once.state() == OnceState::Done {
// SAFETY:
// The closure has been run successfully, so `value` has been initialized
// and will not be modified again.
Some(unsafe { &(*this.data.get()).value })
} else {
None
}
}
/// Forces the evaluation of this lazy value and returns a reference to
/// result. This is equivalent to the `Deref` impl, but is explicit.
///
/// This method will block the calling thread if another initialization
/// routine is currently running.
#[inline]
pub fn force(this: &LazyLock<T, F>) -> &T {
this.once.call_once(|| {
// SAFETY: `call_once` only runs this closure once, ever.
let data = unsafe { &mut *this.data.get() };
let f = unsafe { ManuallyDrop::take(&mut data.f) };
let value = f();
data.value = ManuallyDrop::new(value);
});
// SAFETY:
// There are four possible scenarios:
// * the closure was called and initialized `value`.
// * the closure was called and panicked, so this point is never reached.
// * the closure was not called, but a previous call initialized `value`.
// * the closure was not called because the Once is poisoned, so this point
// is never reached.
// So `value` has definitely been initialized and will not be modified again.
unsafe { &(*this.data.get()).value }
}
}
impl<T, F> Drop for LazyLock<T, F> {
fn drop(&mut self) {
match self.once.state() {
OnceState::New => {}
OnceState::InProgress => unsafe { ManuallyDrop::drop(&mut self.data.get_mut().f) },
OnceState::Done => unsafe { ManuallyDrop::drop(&mut self.data.get_mut().value) },
OnceState::Poisoned => {}
}
}
}
impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
type Target = T;
/// Dereferences the value.
///
/// This method will block the calling thread if another initialization
/// routine is currently running.
#[inline]
fn deref(&self) -> &T {
LazyLock::force(self)
}
}
unsafe impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F> {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment