Struct conquer_once::doc::OnceCell

source ·
pub struct OnceCell<T, B> { /* private fields */ }
Expand description

An interior mutability cell type which allows synchronized one-time initialization and read-only access exclusively after initialization.

Poisoning

A thread that panics in the course of executing its init function or closure poisons the cell. All subsequent accesses to a poisoned cell will propagate this and panic themselves.

Implementations§

source§

impl<T, B> OnceCell<T, B>

source

pub const fn uninit() -> Self

Creates a new uninitialized OnceCell.

source

pub const fn new(value: T) -> Self

Creates a new OnceCell pre-initialized with value.

source

pub fn into_inner(self) -> Option<T>

Consumes self and returns a Some(T) if the OnceCell has previously been successfully initialized or None otherwise.

Panics

This method panics if the OnceCell has been poisoned.

Examples

let uninit: OnceCell<i32> = OnceCell::uninit();
assert!(uninit.into_inner().is_none());

let once = OnceCell::uninit();
once.init_once(|| "initialized");
assert_eq!(once.into_inner(), Some("initialized"));
source

pub fn is_initialized(&self) -> bool

Returns true if the OnceCell has been successfully initialized.

This method will never panic or block.

source

pub fn is_poisoned(&self) -> bool

Returns true if the OnceCell has been poisoned during initialization.

This method will never panic or block.

Once this method has returned true all other means of accessing the OnceCell except for further calls to is_initialized or is_poisoned will panic.

source

pub fn try_get(&self) -> Result<&T, TryGetError>

Returns a reference to the OnceCell’s initialized inner state or an Err.

This method will never blocks.

When this function returns with an Ok result, it is guaranteed that some initialization closure has run and completed. 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).

Errors

This method fails if the OnceCell is either not initialized (Uninit) or is currently being initialized by some other thread (WouldBlock).

Panics

This method panics if the OnceCell has been poisoned.

source

pub unsafe fn get_unchecked(&self) -> &T

Returns a reference to the inner value without checking whether the OnceCell is actually initialized.

Safety

The caller has to ensure that the cell has been successfully initialized, otherwise uninitialized memory will be read.

Examples

This is one safe way to use this method, although try_get is the better alternative:

use conquer_once::OnceCell;

// let cell = ...

let res = if cell.is_initialized() {
    Some(unsafe { cell.get_unchecked() })
} else {
    None
};
source§

impl<T, B: Unblock> OnceCell<T, B>

source

pub fn try_init_once( &self, func: impl FnOnce() -> T ) -> Result<(), TryInitError>

Attempts to initialize the OnceCell with func if is is uninitialized and returns Ok(()) only if func is successfully executed.

This method will never block.

When this function returns with an Ok or Err(AlreadyInit) result, it is guaranteed that some initialization closure 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).

Errors

This method fails, if the initialization of OnceCell has already been completed previously, in which case an AlreadyInit error is returned. If another thread is concurrently in the process of initializing it and this thread would have to block, a WouldBlock error is returned.

Panics

This method panics if the OnceCell has been poisoned.

Examples
use conquer_once::{OnceCell, TryInitError};

let cell = OnceCell::uninit();

// .. in thread 1
let res = cell.try_init_once(|| {
    1
});
assert!(res.is_ok());

// .. in thread 2
let res = cell.try_init_once(|| {
    2
});
assert_eq!(res, Err(TryInitError::AlreadyInit));
source

pub fn try_get_or_init( &self, func: impl FnOnce() -> T ) -> Result<&T, WouldBlockError>

Returns a reference to the OnceCell’s initialized inner state or otherwise attempts to initialize it with func and return the result.

This method never blocks.

When this function returns with an Ok result, it is guaranteed that some initialization closure 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).

Errors

This method only fails if the calling thread would have to block in case another thread is concurrently initializing the OnceCell.

Panics

This method panics if the OnceCell has been poisoned.

source§

impl<T, B: Block> OnceCell<T, B>

source

pub fn get(&self) -> Option<&T>

Returns a reference to the OnceCell’s initialized inner state or None.

This method blocks if another thread has already begun initializing the OnceCell concurrently. See try_get for a non-blocking alternative.

When this function returns with Some, it is guaranteed that some initialization closure has run and completed. 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).

Panics

This method panics if the OnceCell has been poisoned.

Examples
use conquer_once::OnceCell;

let cell = OnceCell::uninit();
assert_eq!(cell.get(), None);
cell.init_once(|| {
    1
});
assert_eq!(cell.get(), Some(&1));
source

pub fn init_once(&self, func: impl FnOnce() -> T)

Attempts to initialize the OnceCell with func if it is uninitialized.

This method blocks if another thread has already begun initializing the OnceCell concurrently.

If the initialization of the OnceCell has already been completed previously, this method returns early with minimal overhead.

When this function returns, it is guaranteed that some initialization closure 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).

Panics

This method panics if the OnceCell has been poisoned.

Examples
use conquer_once::OnceCell;

let cell = OnceCell::uninit();
cell.init_once(|| {
    // expensive calculation
    (0..1_000).map(|i| i * i).sum::<usize>()
});

cell.init_once(|| {
    // any further or concurrent calls to `init_once` will do
    // nothing and return immediately with almost no overhead.
});
source

pub fn get_or_init(&self, func: impl FnOnce() -> T) -> &T

Returns a reference to the OnceCell’s initialized inner state or otherwise attempts to initialize it with func and return the result.

This method blocks if another thread has already begun initializing the OnceCell concurrently. See try_get_or_init for a non-blocking alternative.

When this function returns, it is guaranteed that some initialization closure 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).

Panics

This method panics if the OnceCell has been poisoned.

Trait Implementations§

source§

impl<T: Debug, B> Debug for OnceCell<T, B>

source§

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

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

impl<T, B> Drop for OnceCell<T, B>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<T, B> Send for OnceCell<T, B>where T: Send,

source§

impl<T, B> Sync for OnceCell<T, B>where T: Send + Sync,

Auto Trait Implementations§

§

impl<T, B> !RefUnwindSafe for OnceCell<T, B>

§

impl<T, B> Unpin for OnceCell<T, B>where B: Unpin, T: Unpin,

§

impl<T, B> UnwindSafe for OnceCell<T, B>where B: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

const: unstable · source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

const: unstable · 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<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.
source§

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

§

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

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.