Skip to main content

OnceCell

Struct OnceCell 

Source
pub struct OnceCell<T> { /* private fields */ }
Expand description

A single-threaded async cell initialized at most once.

The first caller to get_or_init runs the initializer. Concurrent callers wait for that initializer and then receive the same reference.

§Differences from other once cells

Initializer futures are local to one runtime thread and may be !Send, unlike tokio::sync::OnceCell on Tokio’s multithreaded runtime. std::sync::OnceLock is synchronous and blocks threads; this type awaits local async initialization without atomics.

§Examples

use std::cell::{Cell, RefCell};
use std::rc::Rc;

use runite::sync::OnceCell;

let cell = Rc::new(OnceCell::new());
let init_count = Rc::new(Cell::new(0));
let observed = Rc::new(RefCell::new(Vec::new()));

for _ in 0..2 {
    runite::spawn({
        let cell = Rc::clone(&cell);
        let init_count = Rc::clone(&init_count);
        let observed = Rc::clone(&observed);
        async move {
            let value = cell
                .get_or_init(|| {
                    let init_count = Rc::clone(&init_count);
                    async move {
                        init_count.set(init_count.get() + 1);
                        runite::yield_now().await;
                        42
                    }
                })
                .await;
            observed.borrow_mut().push(*value);
        }
    });
}

runite::run();

assert_eq!(init_count.get(), 1);
assert_eq!(&*observed.borrow(), &[42, 42]);
assert_eq!(cell.get(), Some(&42));

Implementations§

Source§

impl<T> OnceCell<T>

Source

pub fn new() -> Self

Creates an empty cell.

Source

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

Returns the initialized value, if any.

Returns None while the cell is empty or while an asynchronous initializer is still running. If an initializer is cancelled or panics, the cell returns to the empty state and get() continues to return None until another initializer completes.

Source

pub async fn get_or_init<F, Fut>(&self, f: F) -> &T
where F: FnOnce() -> Fut, Fut: Future<Output = T>,

Returns the cell value, initializing it with f if needed.

Only one caller runs an initializer at a time. Other callers that arrive while initialization is in progress wait until the value is ready.

§Cancellation and panics

If the initializer future is dropped before completing (for example, the awaiting task is aborted) or panics, the cell is reset to its empty state and a waiting caller is woken to retry initialization with its own f. The cell never becomes permanently stuck because an initializer did not finish.

Trait Implementations§

Source§

impl<T> Default for OnceCell<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for OnceCell<T>

§

impl<T> !RefUnwindSafe for OnceCell<T>

§

impl<T> !Send for OnceCell<T>

§

impl<T> !Sync for OnceCell<T>

§

impl<T> !UnwindSafe for OnceCell<T>

§

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

§

impl<T> UnsafeUnpin for OnceCell<T>
where T: UnsafeUnpin,

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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<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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more