Skip to content

Commit 7ef541b

Browse files
committed
glib: Don't drop T if ThreadGuard<T> is dropped on the wrong thread.
1 parent 2fcc1f6 commit 7ef541b

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

glib/src/thread_guard.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Take a look at the license at the top of the repository in the LICENSE file.
22

33
use std::{
4-
mem, ptr,
4+
mem::ManuallyDrop,
55
sync::atomic::{AtomicUsize, Ordering},
66
};
77
fn next_thread_id() -> usize {
@@ -23,7 +23,9 @@ pub fn thread_id() -> usize {
2323
/// Thread guard that only gives access to the contained value on the thread it was created on.
2424
pub struct ThreadGuard<T> {
2525
thread_id: usize,
26-
value: T,
26+
// This is a `ManuallyDrop` so that the automatic drop glue does not drop `T`
27+
// if this `ThreadGuard` is dropped on the wrong thread.
28+
value: ManuallyDrop<T>,
2729
}
2830

2931
impl<T> ThreadGuard<T> {
@@ -38,7 +40,7 @@ impl<T> ThreadGuard<T> {
3840
pub fn new(value: T) -> Self {
3941
Self {
4042
thread_id: thread_id(),
41-
value,
43+
value: ManuallyDrop::new(value),
4244
}
4345
}
4446

@@ -90,7 +92,11 @@ impl<T> ThreadGuard<T> {
9092
"Value accessed from different thread than where it was created"
9193
);
9294

93-
unsafe { ptr::read(&mem::ManuallyDrop::new(self).value) }
95+
// We wrap `self` in `ManuallyDrop` to defuse `ThreadGuard`'s `Drop` impl.
96+
let mut this = ManuallyDrop::new(self);
97+
98+
// SAFETY: We are on the right thread, and this.value will not be touched after this
99+
unsafe { ManuallyDrop::take(&mut this.value) }
94100
}
95101

96102
// rustdoc-stripper-ignore-next
@@ -108,6 +114,9 @@ impl<T> Drop for ThreadGuard<T> {
108114
self.thread_id == thread_id(),
109115
"Value dropped on a different thread than where it was created"
110116
);
117+
118+
// SAFETY: We are on the right thread, and self.value will not be touched after this
119+
unsafe { ManuallyDrop::drop(&mut self.value) }
111120
}
112121
}
113122

0 commit comments

Comments
 (0)