pub struct ProcessLocal<T: 'static> { /* private fields */ }
Expand description

A process local storage which owns its contents.

It is instantiated with the process_local! macro and the primary method is the with method.

The with method yields a reference to the contained value which cannot escape the given closure.

Initialization and Destruction

Initialization is dynamically performed on the first call to with within a process, and values are never destructed. This means if a process finishes normally or panics, the Drop implementation will never be called.

A ProcessLocal’s initializer cannot recursively depend on itself, and using a ProcessLocal in this way will cause the initializer to infinitely recourse on the first call to with.

Examples

use lunatic::{process_local, spawn_link};
use std::cell::RefCell;

process_local!(static FOO: RefCell<u32> = RefCell::new(1));

FOO.with(|f| {
    assert_eq!(*f.borrow(), 1);
    *f.borrow_mut() = 2;
});

// each process starts out with the initial value of 1
let child = spawn_link!(@task || {
    FOO.with(|f| {
        assert_eq!(*f.borrow(), 1);
        *f.borrow_mut() = 3;
    });
});

// wait for the process to complete
let _ = child.result();

// we retain our original value of 2 despite the child process
FOO.with(|f| {
    assert_eq!(*f.borrow(), 2);
});

Implementations§

source§

impl<T: 'static> ProcessLocal<T>

source

pub fn with<F, R>(&'static self, f: F) -> R
where F: FnOnce(&'static T) -> R,

Acquires a reference to the value in this process local.

This will lazily initialize the value if this process has not referenced it yet.

source§

impl<T: 'static> ProcessLocal<Cell<T>>

source

pub fn set(&'static self, value: T)

Sets or initializes the contained value.

Unlike the other methods, this will not run the lazy initializer of the process local. Instead, it will be directly initialized with the given value if it wasn’t initialized yet.

Examples
use std::cell::Cell;

process_local! {
    static X: Cell<i32> = panic!("!");
}

// Calling X.get() here would result in a panic.

X.set(123); // But X.set() is fine, as it skips the initializer above.

assert_eq!(X.get(), 123);
source

pub fn get(&'static self) -> T
where T: Copy,

Returns a copy of the contained value.

This will lazily initialize the value if this process has not referenced it yet.

Examples
use std::cell::Cell;

process_local! {
    static X: Cell<i32> = Cell::new(1);
}

assert_eq!(X.get(), 1);
source

pub fn take(&'static self) -> T
where T: Default,

Takes the contained value, leaving Default::default() in its place.

This will lazily initialize the value if this process has not referenced it yet.

Examples
use std::cell::Cell;

process_local! {
    static X: Cell<Option<i32>> = Cell::new(Some(1));
}

assert_eq!(X.take(), Some(1));
assert_eq!(X.take(), None);
source

pub fn replace(&'static self, value: T) -> T

Replaces the contained value, returning the old value.

This will lazily initialize the value if this process has not referenced it yet.

Examples
use std::cell::Cell;

process_local! {
    static X: Cell<i32> = Cell::new(1);
}

assert_eq!(X.replace(2), 1);
assert_eq!(X.replace(3), 2);
source§

impl<T: 'static> ProcessLocal<RefCell<T>>

source

pub fn with_borrow<F, R>(&'static self, f: F) -> R
where F: FnOnce(Ref<'static, T>) -> R,

Acquires a reference to the contained value.

This will lazily initialize the value if this process has not referenced it yet.

Panics

Panics if the value is currently mutably borrowed.

Example
use std::cell::RefCell;

process_local! {
    static X: RefCell<Vec<i32>> = RefCell::new(Vec::new());
}

X.with_borrow(|v| assert!(v.is_empty()));
source

pub fn with_borrow_mut<F, R>(&'static self, f: F) -> R
where F: FnOnce(RefMut<'static, T>) -> R,

Acquires a mutable reference to the contained value.

This will lazily initialize the value if this process has not referenced it yet.

Panics

Panics if the value is currently borrowed.

Example
use std::cell::RefCell;

process_local! {
    static X: RefCell<Vec<i32>> = RefCell::new(Vec::new());
}

X.with_borrow_mut(|v| v.push(1));

X.with_borrow(|v| assert_eq!(*v, vec![1]));
source

pub fn set(&'static self, value: T)

Sets or initializes the contained value.

Unlike the other methods, this will not run the lazy initializer of the process local. Instead, it will be directly initialized with the given value if it wasn’t initialized yet.

Panics

Panics if the value is currently borrowed.

Examples
use std::cell::RefCell;

process_local! {
    static X: RefCell<Vec<i32>> = panic!("!");
}

// Calling X.with() here would result in a panic.

X.set(vec![1, 2, 3]); // But X.set() is fine, as it skips the initializer above.

X.with_borrow(|v| assert_eq!(*v, vec![1, 2, 3]));
source

pub fn take(&'static self) -> T
where T: Default,

Takes the contained value, leaving Default::default() in its place.

This will lazily initialize the value if this process has not referenced it yet.

Panics

Panics if the value is currently borrowed.

Examples
use std::cell::RefCell;

process_local! {
    static X: RefCell<Vec<i32>> = RefCell::new(Vec::new());
}

X.with_borrow_mut(|v| v.push(1));

let a = X.take();

assert_eq!(a, vec![1]);

X.with_borrow(|v| assert!(v.is_empty()));
source

pub fn replace(&'static self, value: T) -> T

Replaces the contained value, returning the old value.

Panics

Panics if the value is currently borrowed.

Examples
use std::cell::RefCell;

process_local! {
    static X: RefCell<Vec<i32>> = RefCell::new(Vec::new());
}

let prev = X.replace(vec![1, 2, 3]);
assert!(prev.is_empty());

X.with_borrow(|v| assert_eq!(*v, vec![1, 2, 3]));

Trait Implementations§

source§

impl<T: 'static> Debug for ProcessLocal<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for ProcessLocal<T>

§

impl<T> Send for ProcessLocal<T>

§

impl<T> Sync for ProcessLocal<T>

§

impl<T> Unpin for ProcessLocal<T>

§

impl<T> UnwindSafe for ProcessLocal<T>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.