fragile/lib.rs
1//! This library provides wrapper types that permit sending non `Send` types to
2//! other threads and use runtime checks to ensure safety.
3//!
4//! It provides three types: `Fragile<T>` and `Sticky<T>` which are similar in nature
5//! but have different behaviors with regards to how destructors are executed and
6//! the extra `SemiSticky<T>` type which uses `Sticky<T>` if the value has a
7//! destructor and `Fragile<T>` if it does not.
8//!
9//! Both types wrap a value and provide a `Send` bound. Neither of the types permit
10//! access to the enclosed value unless the thread that wrapped the value is attempting
11//! to access it. The difference between the two types starts playing a role once
12//! destructors are involved.
13//!
14//! A `Fragile<T>` will actually send the `T` from thread to thread but will only
15//! permit the original thread to invoke the destructor. If the value gets dropped
16//! in a different thread, the destructor will panic.
17//!
18//! A `Sticky<T>` on the other hand does not actually send the `T` around but keeps
19//! it stored in the original thread's thread local storage. If it gets dropped
20//! in the originating thread it gets cleaned up immediately, otherwise it leaks
21//! until the thread shuts down naturally.
22//!
23//! # Example usage
24//!
25//! ```
26//! use std::thread;
27//! use fragile::Fragile;
28//!
29//! // creating and using a fragile object in the same thread works
30//! let val = Fragile::new(true);
31//! assert_eq!(*val.get(), true);
32//! assert!(val.try_get().is_ok());
33//!
34//! // once send to another thread it stops working
35//! thread::spawn(move || {
36//! assert!(val.try_get().is_err());
37//! }).join()
38//! .unwrap();
39//! ```
40//!
41//! # Why?
42//!
43//! Most of the time trying to use this crate is going to indicate some code smell. But
44//! there are situations where this is useful. For instance you might have a bunch of
45//! non `Send` types but want to work with a `Send` error type. In that case the non
46//! sendable extra information can be contained within the error and in cases where the
47//! error did not cross a thread boundary yet extra information can be obtained.
48mod errors;
49mod fragile;
50mod semisticky;
51mod sticky;
52
53pub use crate::errors::InvalidThreadAccess;
54pub use crate::fragile::Fragile;
55pub use crate::semisticky::SemiSticky;
56pub use crate::sticky::Sticky;