[][src]Crate double_checked_cell_async

A thread-safe lazily initialized cell using double-checked locking.

Provides a memory location that can be safely shared between threads and initialized at most once. Once the cell is initialized it becomes immutable.

You can only initialize a DoubleCheckedCell<T> once, but then it is more efficient than a Mutex<Option<T>>.

Examples

use double_checked_cell::DoubleCheckedCell;
use futures::future::ready;

let cell = DoubleCheckedCell::new();

// The cell starts uninitialized.
assert_eq!(cell.get().await, None);

// Perform potentially expensive initialization.
let value = cell.get_or_init(async { 21 + 21 }).await;
assert_eq!(*value, 42);
assert_eq!(cell.get().await, Some(&42));

// The cell is already initialized.
let value = cell.get_or_init(async { unreachable!() }).await;
assert_eq!(*value, 42);
assert_eq!(cell.get().await, Some(&42));

Errors

DoubleCheckedCell supports fallible initialization.

use tokio::fs::File;
use tokio::prelude::*;
use double_checked_cell::DoubleCheckedCell;

let cell = DoubleCheckedCell::new();

let contents: Result<_, tokio::io::Error> = cell.get_or_try_init(async {
    let mut file = File::open("not-found.txt").await?;
    let mut contents = String::new();
    file.read_to_string(&mut contents).await?;
    Ok(contents)
}).await;

// File not found.
assert!(contents.is_err());

// Cell remains uninitialized for now.
assert_eq!(cell.get().await, None);

Unwind safety

If an initialization closure panics, the DoubleCheckedCell remains uninitialized, however the catch_unwind future combinator currently can't be applied to the futures returned from get_or_init and get_or_try_init.

Structs

DoubleCheckedCell

A thread-safe lazily initialized cell.