Crates.io | threadbound |
lib.rs | threadbound |
version | 0.1.7 |
source | src |
created_at | 2018-11-17 23:39:45.92698 |
updated_at | 2023-07-15 21:11:02.924528 |
description | Make any value Sync but only available on its original thread. |
homepage | |
repository | https://github.com/dtolnay/threadbound |
max_upload_size | |
id | 97319 |
size | 21,106 |
ThreadBound is a wrapper that binds a value to its original thread. The wrapper
gets to be Sync
and Send
but only the original thread on which the
ThreadBound was constructed can retrieve the underlying value.
[dependencies]
threadbound = "0.1"
Version requirement: rustc 1.31+
extern crate threadbound;
use std::marker::PhantomData;
use std::rc::Rc;
use std::sync::Arc;
use threadbound::ThreadBound;
// Neither Send nor Sync. Maybe the index points into a
// thread-local interner.
#[derive(Copy, Clone)]
struct Span {
index: u32,
marker: PhantomData<Rc<()>>,
}
// Error types are always supposed to be Send and Sync.
// We can use ThreadBound to make it so.
struct Error {
span: ThreadBound<Span>,
message: String,
}
fn main() {
let err = Error {
span: ThreadBound::new(Span {
index: 99,
marker: PhantomData,
}),
message: "fearless concurrency".to_owned(),
};
// Original thread can see the contents.
assert_eq!(err.span.get_ref().unwrap().index, 99);
let err = Arc::new(err);
let err2 = err.clone();
std::thread::spawn(move || {
// Other threads cannot get access. Maybe they use
// a default value or a different codepath.
assert!(err2.span.get_ref().is_none());
});
// Original thread can still see the contents.
assert_eq!(err.span.get_ref().unwrap().index, 99);
}