Struct atomic_cell::StaticCell
[−]
[src]
pub struct StaticCell<T> where T: Clone {
// some fields omitted
}
A cell holding values protected by an atomic lock.
This cell is designed to be instantiated as a global variable, to
hold a single value and to distribute it to threads as needed. It
was initially designed to distribute clones of Sender
to
hundreds of clients across dozens of modules without having to
pass these senders as argument through hundreds of intermediate
functions.
Example
#![feature(const_fn)] use std::thread; use std::sync::mpsc::{channel, Sender}; use std::ops::Add; use atomic_cell::StaticCell; // Sender cannot be defined as a `static` for two reasons: // - it does not implement `Sync`; // - it has a destructor. // So let's implement it as a `StaticCell`. static CELL: StaticCell<Sender<u32>> = StaticCell::new(); fn main() { let (sender, receiver) = channel(); let _guard = CELL.init(sender); // From this point and until `_guard` is dropped, `CELL` owns `sender`. for i in 0..10 { thread::spawn(move || { // Any thread can now access clones of `sender`. let sender = CELL.get().unwrap(); sender.send(i).unwrap(); }); } // Make sure that all data was received properly. assert_eq!(receiver.iter().take(10).fold(0, Add::add), 45); // When we leave `main()`, `_guard` will go out of scope and // will be dropped. This will cause `sender` to be dropped. }
Performance
This cell is optimized for low contention. If there is no
contention, each call to get
is resolved as a single
(sequentially consistant) atomic read. In presence of high
contention on a single cell, though, performance may degrade
considerably.
Resource-safety
Unlike other kinds of static holders, values in StaticCell
are
scoped and will be dropped, once the guard is dropped.
Methods
impl<T> StaticCell<T> where T: Clone
const fn new() -> Self
Create an empty cell.
Call init
to fill the cell.
fn init<'a>(&'a self, value: T) -> CleanGuard<'a>
Initialize the cell.
This methods returns a guard, which will drop value
once it
is dropped itself. Once this is done, self
will return to
being an empty cell. It will, however, remain initialized and
cannot ever be initialized again.
Panics
This method panicks if the cell is already initialized, or if
initialization is racing with a call to get
.
fn get(&self) -> Option<Box<T>>
Get a clone of the value held by the cell.
Returns None
if the cell is empty, either because it is not
initialized or because the guard has been dropped.
Receiving None
is almost always a programming error, so
client code is encouraged to unwrap()
immediately.
Performance
This methods uses an atomic spinlock. With low contention, it
is generally quite fast (assuming that clone()
is itself
fast). In case of high contention, performance may degrade
considerably. In case of doubt, ou may wish to ensure that
your code calls clone()
before entering a
perfirmance-critical or high-contention section.
Panics
This method panicks if the call to value.clone()
causes a
panic. However, the cell remains usable.
This method may panick if it is racing with init()
. Just
make sure that initialization is complete before using this
cell, right?