pub struct Once<T = (), R = Spin> { /* private fields */ }
Expand description
A primitive that provides lazy one-time initialization.
Unlike its std::sync
equivalent, this is generalized such that the closure returns a
value to be stored by the Once
(std::sync::Once
can be trivially emulated with
Once
).
Because Once::new
is const
, this primitive may be used to safely initialize statics.
Examples
use spin;
static START: spin::Once = spin::Once::new();
START.call_once(|| {
// run initialization here
});
Implementations§
source§impl<T, R: RelaxStrategy> Once<T, R>
impl<T, R: RelaxStrategy> Once<T, R>
sourcepub fn call_once<F: FnOnce() -> T>(&self, f: F) -> &T
pub fn call_once<F: FnOnce() -> T>(&self, f: F) -> &T
Performs an initialization routine once and only once. The given closure
will be executed if this is the first time call_once
has been called,
and otherwise the routine will not be invoked.
This method will block the calling thread if another initialization routine is currently running.
When this function returns, it is guaranteed that some initialization has run and completed (it may not be the closure specified). The returned pointer will point to the result from the closure that was run.
Panics
This function will panic if the Once
previously panicked while attempting
to initialize. This is similar to the poisoning behaviour of std::sync
’s
primitives.
Examples
use spin;
static INIT: spin::Once<usize> = spin::Once::new();
fn get_cached_val() -> usize {
*INIT.call_once(expensive_computation)
}
fn expensive_computation() -> usize {
// ...
}
sourcepub fn try_call_once<F: FnOnce() -> Result<T, E>, E>(
&self,
f: F
) -> Result<&T, E>
pub fn try_call_once<F: FnOnce() -> Result<T, E>, E>( &self, f: F ) -> Result<&T, E>
This method is similar to call_once
, but allows the given closure to
fail, and lets the Once
in a uninitialized state if it does.
This method will block the calling thread if another initialization routine is currently running.
When this function returns without error, it is guaranteed that some initialization has run and completed (it may not be the closure specified). The returned reference will point to the result from the closure that was run.
Panics
This function will panic if the Once
previously panicked while attempting
to initialize. This is similar to the poisoning behaviour of std::sync
’s
primitives.
Examples
use spin;
static INIT: spin::Once<usize> = spin::Once::new();
fn get_cached_val() -> Result<usize, String> {
INIT.try_call_once(expensive_fallible_computation).map(|x| *x)
}
fn expensive_fallible_computation() -> Result<usize, String> {
// ...
}
sourcepub fn wait(&self) -> &T
pub fn wait(&self) -> &T
Spins until the Once
contains a value.
Note that in releases prior to 0.7
, this function had the behaviour of Once::poll
.
Panics
This function will panic if the Once
previously panicked while attempting
to initialize. This is similar to the poisoning behaviour of std::sync
’s
primitives.
sourcepub fn poll(&self) -> Option<&T>
pub fn poll(&self) -> Option<&T>
Like Once::get
, but will spin if the Once
is in the process of being
initialized. If initialization has not even begun, None
will be returned.
Note that in releases prior to 0.7
, this function was named wait
.
Panics
This function will panic if the Once
previously panicked while attempting
to initialize. This is similar to the poisoning behaviour of std::sync
’s
primitives.
source§impl<T, R> Once<T, R>
impl<T, R> Once<T, R>
sourcepub const fn initialized(data: T) -> Self
pub const fn initialized(data: T) -> Self
Creates a new initialized Once
.
sourcepub fn as_mut_ptr(&self) -> *mut T
pub fn as_mut_ptr(&self) -> *mut T
Retrieve a pointer to the inner data.
While this method itself is safe, accessing the pointer before the Once
has been
initialized is UB, unless this method has already been written to from a pointer coming
from this method.
sourcepub fn get(&self) -> Option<&T>
pub fn get(&self) -> Option<&T>
Returns a reference to the inner value if the Once
has been initialized.
sourcepub unsafe fn get_unchecked(&self) -> &T
pub unsafe fn get_unchecked(&self) -> &T
Returns a reference to the inner value on the unchecked assumption that the Once
has been initialized.
Safety
This is extremely unsafe if the Once
has not already been initialized because a reference to uninitialized
memory will be returned, immediately triggering undefined behaviour (even if the reference goes unused).
However, this can be useful in some instances for exposing the Once
to FFI or when the overhead of atomically
checking initialization is unacceptable and the Once
has already been initialized.
sourcepub unsafe fn get_mut_unchecked(&mut self) -> &mut T
pub unsafe fn get_mut_unchecked(&mut self) -> &mut T
Returns a mutable reference to the inner value
Safety
This is extremely unsafe if the Once
has not already been initialized because a reference to uninitialized
memory will be returned, immediately triggering undefined behaviour (even if the reference goes unused).
However, this can be useful in some instances for exposing the Once
to FFI or when the overhead of atomically
checking initialization is unacceptable and the Once
has already been initialized.
sourcepub fn try_into_inner(self) -> Option<T>
pub fn try_into_inner(self) -> Option<T>
sourcepub unsafe fn into_inner_unchecked(self) -> T
pub unsafe fn into_inner_unchecked(self) -> T
Returns a the inner value if the Once
has been initialized.
Safety
This is extremely unsafe if the Once
has not already been initialized because a reference to uninitialized
memory will be returned, immediately triggering undefined behaviour (even if the reference goes unused)
This can be useful, if Once
has already been initialized, and you want to bypass an
option check.
sourcepub fn is_completed(&self) -> bool
pub fn is_completed(&self) -> bool
Checks whether the value has been initialized.
This is done using Acquire
ordering, and
therefore it is safe to access the value directly via
get_unchecked
if this returns true.