RacyLock

Struct RacyLock 

Source
pub struct RacyLock<T, F = fn() -> T> { /* private fields */ }
Expand description

Thread-safe, non-blocking, lazily evaluated lock with the same interface as std::sync::LazyLock.

Concurrent threads will race to set the value atomically, and memory allocated by losing threads will be dropped immediately after they fail to set the pointer.

The underlying implementation is based on once_cell::race::OnceBox which relies on core::sync::atomic::AtomicPtr to ensure that the data race results in a single successful write to the relevant pointer, namely the first write. See https://github.com/matklad/once_cell/blob/v1.19.0/src/race.rs#L294.

Performs lazy evaluation and can be used for statics.

Implementations§

Source§

impl<T, F> RacyLock<T, F>
where F: Fn() -> T,

Source

pub const fn new(f: F) -> Self

Creates a new lazy, racy value with the given initializing function.

Source

pub fn force(this: &RacyLock<T, F>) -> &T

Forces the evaluation of the locked value and returns a reference to the result. This is equivalent to the Self::deref.

There is no blocking involved in this operation. Instead, concurrent threads will race to set the underlying pointer. Memory allocated by losing threads will be dropped immediately after they fail to set the pointer.

This function’s interface is designed around std::sync::LazyLock::force but the implementation is derived from once_cell::race::OnceBox::get_or_try_init.

Trait Implementations§

Source§

impl<T, F> Debug for RacyLock<T, F>
where T: Debug, F: Fn() -> T,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default> Default for RacyLock<T>

Source§

fn default() -> RacyLock<T>

Creates a new lock that will evaluate the underlying value based on T::default.

Source§

impl<T, F> Deref for RacyLock<T, F>
where F: Fn() -> T,

Source§

fn deref(&self) -> &T

Either sets or retrieves the value, and dereferences it.

See Self::force for more details.

Source§

type Target = T

The resulting type after dereferencing.
Source§

impl<T, F> Drop for RacyLock<T, F>

Source§

fn drop(&mut self)

Drops the underlying pointer.

Source§

impl<T: Send, F: Send> Send for RacyLock<T, F>

Source§

impl<T: Send + Sync, F: Send> Sync for RacyLock<T, F>

Auto Trait Implementations§

§

impl<T, F = fn() -> T> !Freeze for RacyLock<T, F>

§

impl<T, F> RefUnwindSafe for RacyLock<T, F>
where F: RefUnwindSafe,

§

impl<T, F> Unpin for RacyLock<T, F>
where F: Unpin,

§

impl<T, F> UnwindSafe for RacyLock<T, F>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.