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?

Trait Implementations

impl<T> Sync for StaticCell<T> where T: Clone

impl<T> CleanMeUp for StaticCell<T> where T: Clone

fn clean(&self)