Crate double_checked_cell
source ·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 instanciatingDoubleCheckedCell
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.