diff --git a/actix-rt/CHANGES.md b/actix-rt/CHANGES.md index 5f52876d..c82a0d07 100644 --- a/actix-rt/CHANGES.md +++ b/actix-rt/CHANGES.md @@ -1,5 +1,12 @@ # Changes +## [0.2.5] - 2019-09-02 + +### Added + +* Add arbiter specific storage + + ## [0.2.4] - 2019-07-17 ### Changed diff --git a/actix-rt/Cargo.toml b/actix-rt/Cargo.toml index 067219d7..8131ed19 100644 --- a/actix-rt/Cargo.toml +++ b/actix-rt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-rt" -version = "0.2.4" +version = "0.2.5" authors = ["Nikolay Kim "] description = "Actix runtime" keywords = ["network", "framework", "async", "futures"] diff --git a/actix-rt/src/arbiter.rs b/actix-rt/src/arbiter.rs index 88bcdbfb..285ad3c9 100644 --- a/actix-rt/src/arbiter.rs +++ b/actix-rt/src/arbiter.rs @@ -1,3 +1,4 @@ +use std::any::{Any, TypeId}; use std::cell::{Cell, RefCell}; use std::collections::HashMap; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -17,6 +18,7 @@ thread_local!( static ADDR: RefCell> = RefCell::new(None); static RUNNING: Cell = Cell::new(false); static Q: RefCell>>> = RefCell::new(Vec::new()); + static STORAGE: RefCell>> = RefCell::new(HashMap::new()); ); pub(crate) static COUNT: AtomicUsize = AtomicUsize::new(0); @@ -56,6 +58,7 @@ impl Arbiter { let arb = Arbiter(tx); ADDR.with(|cell| *cell.borrow_mut() = Some(arb.clone())); RUNNING.with(|cell| cell.set(false)); + STORAGE.with(|cell| cell.borrow_mut().clear()); Arbiter::spawn(ArbiterController { stop: None, rx }); arb @@ -90,6 +93,7 @@ impl Arbiter { let (stop, stop_rx) = channel(); RUNNING.with(|cell| cell.set(true)); + STORAGE.with(|cell| cell.borrow_mut().clear()); System::set_current(sys); @@ -202,6 +206,50 @@ impl Arbiter { }))); rx } + + /// Set item to arbiter storage + pub fn set_item(item: T) { + STORAGE.with(move |cell| cell.borrow_mut().insert(TypeId::of::(), Box::new(item))); + } + + /// Check if arbiter storage contains item + pub fn contains_item() -> bool { + STORAGE.with(move |cell| cell.borrow().get(&TypeId::of::()).is_some()) + } + + /// Get a reference to a type previously inserted on this arbiter's storage. + /// + /// Panics is item is not inserted + pub fn get_item(mut f: F) -> R + where + F: FnMut(&T) -> R, + { + STORAGE.with(move |cell| { + let st = cell.borrow(); + let item = st + .get(&TypeId::of::()) + .and_then(|boxed| (&**boxed as &(dyn Any + 'static)).downcast_ref()) + .unwrap(); + f(item) + }) + } + + /// Get a mutable reference to a type previously inserted on this arbiter's storage. + /// + /// Panics is item is not inserted + pub fn get_mut_item(mut f: F) -> R + where + F: FnMut(&mut T) -> R, + { + STORAGE.with(move |cell| { + let mut st = cell.borrow_mut(); + let item = st + .get_mut(&TypeId::of::()) + .and_then(|boxed| (&mut **boxed as &mut (dyn Any + 'static)).downcast_mut()) + .unwrap(); + f(item) + }) + } } struct ArbiterController {