Crate thread_safe[−][src]
Expand description
Let’s say you have some thread-unsafe data. For whatever reason, it can’t be used outside of the thread it originated in. This thread-unsafe data is a component of a larger data struct that does need to be sent around between other threads.
The ThreadSafe
contains data that can only be utilized in the thread it was created in. When a reference
is attempted to be acquired to the interior data, it checks for the current thread it comes from.
ThreadKey
The ThreadKey
is a wrapper around ThreadId
, but !Send
. This allows one to certify that the current
thread has the given ThreadId
, without having to go through thread::current().id()
.
Example
use std::{cell::Cell, sync::{Arc, atomic}, thread}; use thread_safe::ThreadSafe; #[derive(Debug)] struct InnerData { counter: atomic::AtomicUsize, other_counter: ThreadSafe<Cell<usize>>, } fn increment_data(data: &InnerData) { data.counter.fetch_add(1, atomic::Ordering::SeqCst); if let Ok(counter) = data.other_counter.try_get_ref() { counter.set(counter.get() + 1); } } let data = Arc::new(InnerData { counter: atomic::AtomicUsize::new(0), other_counter: ThreadSafe::new(Cell::new(0)), }); let mut handles = vec![]; for _ in 0..10 { let data = data.clone(); handles.push(thread::spawn(move || increment_data(&data))); } increment_data(&data); for handle in handles { handle.join().unwrap(); } let data = Arc::try_unwrap(data).unwrap(); assert_eq!(data.counter.load(atomic::Ordering::Relaxed), 11); assert_eq!(data.other_counter.get_ref().get(), 1);
Structs
Error type for “we are not in the current thread”.
A ThreadId
that is guaranteed to refer to the current thread, since this is !Send
.
The whole point.