blob: a5783c3874a9d2dad0fb47be2b7b4f36cbc7efed [file] [log] [blame]
//! 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 crate::errors::InvalidThreadAccess;
pub use crate::fragile::Fragile;
pub use crate::semisticky::SemiSticky;
pub use crate::sticky::Sticky;