dtolnay / dtolnay/threadbound

Use ManuallyDrop to allow non-Copy T

Open
#6 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
40
Forks
6
PR merge metrics
No merged PRs in 30d

Description

I'm working with Slint, and it doesn't allow multithreading UI stuff (ie. the types are not Send) and yet it requires all callbacks to be `'static`, which was quite a conundrum. The easy solution is to use a thread_local static, but that doesn't feel right. I found this crate and I wanted to store my data as a static `LazyLock>`, but it turns out that isn't allowed because App isn't Copy. I ended up with this custom thing inspired by it:
```rust
pub struct ThreadChecked {
value: ManuallyDrop,
thread_id: ThreadId
}

impl ThreadChecked {
pub fn new(value: T) -> Self {
Self {
value: ManuallyDrop::new(value),
thread_id: std::thread::current().id()
}
}

fn check(&self) {
if std::thread::current().id() != self.thread_id {
panic!("{} value was accessed from the wrong thread", type_name::());
}
}
}

unsafe impl Send for ThreadChecked {}
unsafe impl Sync for ThreadChecked {}

impl Default for ThreadChecked {
fn default() -> Self {
Self::new(Default::default())
}
}

impl Drop for ThreadChecked {
fn drop(&mut self) {
if std::thread::current().id() != self.thread_id {
panic!("{} value was dropped from the wrong thread, leaking it!", type_name::());
} else {
unsafe {
ManuallyDrop::drop(&mut self.value);
}
}
}
}

impl Deref for ThreadChecked {
type Target = T;

fn deref(&self) -> &T {
self.check();
&self.value
}
}

impl DerefMut for ThreadChecked {
fn deref_mut(&mut self) -> &mut T {
self.check();
&mut self.value
}
}
```
See, Rust allows you to simply not drop values if you don't want to, so you can safely just use ManuallyDrop to prevent drop from being called in the wrong thread. I also added a panic there to mitigate the danger of the value being leaked silently. My suggestion is that this crate do the same thing so it can drop the Copy restriction and be useful in more cases.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.