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
//! This library provides wrapper types that permit sending non `Send` types to //! other threads and use runtime checks to ensure safety. //! //! It provides three types: `Fragile<T>` and `Sticky<T>` which are similar in nature //! but have different behaviors with regards to how destructors are executed and //! the extra `SemiSticky<T>` type which uses `Sticky<T>` if the value has a //! destructor and `Fragile<T>` if it does not. //! //! Both types wrap a value and provide a `Send` bound. Neither of the types permit //! access to the enclosed value unless the thread that wrapped the value is attempting //! to access it. The difference between the two types starts playing a role once //! destructors are involved. //! //! A `Fragile<T>` will actually send the `T` from thread to thread but will only //! permit the original thread to invoke the destructor. If the value gets dropped //! in a different thread, the destructor will panic. //! //! A `Sticky<T>` on the other hand does not actually send the `T` around but keeps //! it stored in the original thread's thread local storage. If it gets dropped //! in the originating thread it gets cleaned up immediately, otherwise it leaks //! until the thread shuts down naturally. //! //! # Example usage //! //! ``` //! use std::thread; //! use fragile::Fragile; //! //! // creating and using a fragile object in the same thread works //! let val = Fragile::new(true); //! assert_eq!(*val.get(), true); //! assert!(val.try_get().is_ok()); //! //! // once send to another thread it stops working //! thread::spawn(move || { //! assert!(val.try_get().is_err()); //! }).join() //! .unwrap(); //! ``` //! //! # Why? //! //! Most of the time trying to use this crate is going to indicate some code smell. But //! there are situations where this is useful. For instance you might have a bunch of //! non `Send` types but want to work with a `Send` error type. In that case the non //! sendable extra information can be contained within the error and in cases where the //! error did not cross a thread boundary yet extra information can be obtained. mod errors; mod fragile; mod semisticky; mod sticky; pub use errors::InvalidThreadAccess; pub use fragile::Fragile; pub use semisticky::SemiSticky; pub use sticky::Sticky;