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;
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§
- Double
Checked Cell - A thread-safe lazily initialized cell.