1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
//! This crate implements an execution context for Rust. An execution context //! carries data through a logical flow of execution. //! //! This is heavily inspired by the .NET `ExecutionContext` system as an //! experiment if such an API would make sense in Rust. //! //! The main differences to the system in .NET: //! //! * This purely implements an execution context and not a synchronization //! context. As such the implementation is simplified. //! * This provides the ability to permanently disable the flow propagation. //! * This crate refers to "ambient data" and "async locals" as "flow-local data". //! * Capturing always returns an execution context even if the flow is //! suppressed. Consequently the run method is no longer static but //! stored on the instance. //! * This uses atomic reference counting underneath the hood instead of //! using a garbage collector. This also means that performance //! characteristics will be different. //! * `FlowLocal` data have a initialization expression that is invoked if //! no local data is stored in the current flow. //! //! # Example Usage //! //! ``` //! #[macro_use] //! extern crate execution_context; //! //! use execution_context::ExecutionContext; //! use std::env; //! use std::thread; //! //! flow_local!(static LOCALE: String = env::var("LANG").unwrap_or_else(|_| "en_US".into())); //! //! fn main() { //! println!("the current locale is {}", LOCALE.get()); //! LOCALE.set("de_DE".into()); //! println!("changing locale to {}", LOCALE.get()); //! //! let ec = ExecutionContext::capture(); //! thread::spawn(move || { //! ec.run(|| { //! println!("the locale in the child thread is {}", LOCALE.get()); //! LOCALE.set("fr_FR".into()); //! println!("the new locale in the child thread is {}", LOCALE.get()); //! }); //! }).join().unwrap(); //! //! println!("the locale of the parent thread is again {}", LOCALE.get()); //! } //! ``` //! //! This example will give the following output assuming no default language was //! set as environment variable (or the environment variable is `en_US`): //! //! ```plain //! the current locale is en_US //! changing locale to de_DE //! the locale in the child thread is de_DE //! the new locale in the child thread is fr_FR //! the locale of the parent thread is again de_DE //! ``` extern crate im; #[macro_use] extern crate lazy_static; mod ctx; mod data; pub use ctx::*; pub use data::*;