Crate double_checked_cell [−] [src]
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(|| { panic!("initilization does not run again") }); 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);
Poisoning
DoubleCheckedCell
achieves unwind safety by implementing "poisoning".
If an initilization closure is executed and panics, the DoubleCheckedCell
becomes poisoned. Any subsequent reads will then also panic.
use std::panic; use double_checked_cell::DoubleCheckedCell; let cell = DoubleCheckedCell::new(); // Cell gets poisoned. assert!(panic::catch_unwind(|| { cell.get_or_init(|| panic!("oh no!")); }).is_err()); // Now it is poisoned forever. assert!(panic::catch_unwind(|| { cell.get_or_init(|| true); }).is_err());
Structs
DoubleCheckedCell |
A thread-safe lazily initialized cell. |