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.