Struct Once
pub struct Once(/* private field */);
A synchronization primitive which can be used to run a one-time initialization. Useful for one-time initialization for globals, FFI or related functionality.
Differences from the standard library Once
- Only requires 1 byte of space, instead of 1 word.
- Not required to be
'static. - Relaxed memory barriers in the fast path, which can significantly improve performance on some architectures.
- Efficient handling of micro-contention using adaptive spinning.
Examples
use Once;
static START: Once = new;
START.call_once;
Implementations
impl Once
const fn new() -> OnceCreates a new
Oncevalue.fn state(&self) -> OnceStateReturns the current state of this
Once.fn call_once<F>(&self, f: F) where F: FnOnce(),Performs an initialization routine once and only once. The given closure will be executed if this is the first time
call_oncehas 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). It is also guaranteed that any memory writes performed by the executed closure can be reliably observed by other threads at this point (there is a happens-before relation between the closure and code executing after the return).
Examples
use Once; static mut VAL: usize = 0; static INIT: Once = new; // Accessing a `static mut` is unsafe much of the time, but if we do so // in a synchronized fashion (e.g. write once or read all) then we're // good to go! // // This function will only call `expensive_computation` once, and will // otherwise always return the value returned from the first invocation.Panics
The closure
fwill only be executed once if this is called concurrently amongst many threads. If that closure panics, however, then it will poison thisOnceinstance, causing all future invocations ofcall_onceto also panic.fn call_once_force<F>(&self, f: F) where F: FnOnce(OnceState),Performs the same function as
call_onceexcept ignores poisoning.If this
Oncehas been poisoned (some initialization panicked) then this function will continue to attempt to call initialization functions until one of them doesn't panic.The closure
fis yielded a structure which can be used to query the state of thisOnce(whether initialization has previously panicked or not).
Trait Implementations
impl Debug for Once
fn fmt(&self, f: &mut Formatter<'_>) -> Result
impl Default for Once
fn default() -> Once
Auto Trait Implementations
impl !Freeze for Once
impl RefUnwindSafe for Once
impl Send for Once
impl Sync for Once
impl Unpin for Once
impl UnsafeUnpin for Once
impl UnwindSafe for Once
Blanket Implementations
impl<T> Any for Once
where
T: 'static + ?Sized,
fn type_id(&self) -> TypeId
impl<T> Borrow<T> for Once
where
T: ?Sized,
fn borrow(&self) -> &T
impl<T> BorrowMut<T> for Once
where
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> From<T> for Once
fn from(t: T) -> TReturns the argument unchanged.
impl<T, U> Into<U> for Once
where
U: From<T>,
fn into(self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom<U> for Once
where
U: Into<T>,
type Error = never;fn try_from(value: U) -> Result<T, never>
impl<T, U> TryInto<U> for Once
where
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error;fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>