Expand description

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;

let cell = DoubleCheckedCell::new();

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

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

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

Errors

DoubleCheckedCell supports fallible initialization.

use std::fs::File;
use std::io;
use std::io::prelude::*;
use double_checked_cell::DoubleCheckedCell;

let cell = DoubleCheckedCell::new();

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

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

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

Unwind safety

If an initialization closure panics, the DoubleCheckedCell remains uninitialized. Initialization can be retried later, there is no poisoning.

use std::panic;
use double_checked_cell::DoubleCheckedCell;

let cell = DoubleCheckedCell::new();

// Panic during initialization.
assert!(panic::catch_unwind(|| {
    cell.get_or_init(|| panic!("oh no!"));
}).is_err());

// Cell remains uninitialized.
assert!(cell.get().is_none());

Cargo features

  • parking_lot_mutex: Internally use mutexes backed by parking_lot. Optional.

  • const_fn: Allows instanciating DoubleCheckedCell in const context. Can be used as a replacement for lazy_static. Currently nightly only. Optional.

    static LAZY_STATIC: DoubleCheckedCell<u32> = DoubleCheckedCell::new();

Structs

A thread-safe lazily initialized cell.