Skip to content

Commit d8be469

Browse files
authored
Merge pull request #1176 from Aandreba/manually_drop_block_ref_guard_inner
Switch from 'Option' to 'ManuallyDrop' for blocking guard's inner
2 parents e664064 + 09530bf commit d8be469

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

godot-cell/src/blocking_guards.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
77

8+
use std::mem::ManuallyDrop;
89
use std::ops::{Deref, DerefMut};
910
use std::sync::{Arc, Condvar, Mutex};
1011

@@ -16,7 +17,7 @@ use crate::guards::{MutGuard, RefGuard};
1617
/// See [`panicking::RefGuard`](crate::panicking::RefGuard) for more details.
1718
#[derive(Debug)]
1819
pub struct RefGuardBlocking<'a, T> {
19-
inner: Option<RefGuard<'a, T>>,
20+
inner: ManuallyDrop<RefGuard<'a, T>>,
2021
mut_condition: Arc<Condvar>,
2122
state: Arc<Mutex<ThreadTracker>>,
2223
}
@@ -28,7 +29,7 @@ impl<'a, T> RefGuardBlocking<'a, T> {
2829
state: Arc<Mutex<ThreadTracker>>,
2930
) -> Self {
3031
Self {
31-
inner: Some(inner),
32+
inner: ManuallyDrop::new(inner),
3233
mut_condition,
3334
state,
3435
}
@@ -39,7 +40,7 @@ impl<'a, T> Deref for RefGuardBlocking<'a, T> {
3940
type Target = <RefGuard<'a, T> as Deref>::Target;
4041

4142
fn deref(&self) -> &Self::Target {
42-
self.inner.as_ref().unwrap().deref()
43+
self.inner.deref().deref()
4344
}
4445
}
4546

@@ -49,7 +50,8 @@ impl<T> Drop for RefGuardBlocking<'_, T> {
4950

5051
state_lock.decrement_current_thread_shared_count();
5152

52-
drop(self.inner.take());
53+
// SAFETY: guard is dropped exactly once, here.
54+
unsafe { ManuallyDrop::drop(&mut self.inner) };
5355

5456
self.mut_condition.notify_one();
5557
drop(state_lock);
@@ -61,7 +63,7 @@ impl<T> Drop for RefGuardBlocking<'_, T> {
6163
/// See [`panicking::MutGuard`](crate::panicking::MutGuard) for more details.
6264
#[derive(Debug)]
6365
pub struct MutGuardBlocking<'a, T> {
64-
inner: Option<MutGuard<'a, T>>,
66+
inner: ManuallyDrop<MutGuard<'a, T>>,
6567
mut_condition: Arc<Condvar>,
6668
immut_condition: Arc<Condvar>,
6769
}
@@ -73,7 +75,7 @@ impl<'a, T> MutGuardBlocking<'a, T> {
7375
immut_condition: Arc<Condvar>,
7476
) -> Self {
7577
Self {
76-
inner: Some(inner),
78+
inner: ManuallyDrop::new(inner),
7779
immut_condition,
7880
mut_condition,
7981
}
@@ -84,19 +86,20 @@ impl<'a, T> Deref for MutGuardBlocking<'a, T> {
8486
type Target = <MutGuard<'a, T> as Deref>::Target;
8587

8688
fn deref(&self) -> &Self::Target {
87-
self.inner.as_ref().unwrap().deref()
89+
self.inner.deref().deref()
8890
}
8991
}
9092

9193
impl<T> DerefMut for MutGuardBlocking<'_, T> {
9294
fn deref_mut(&mut self) -> &mut Self::Target {
93-
self.inner.as_mut().unwrap().deref_mut()
95+
self.inner.deref_mut().deref_mut()
9496
}
9597
}
9698

9799
impl<T> Drop for MutGuardBlocking<'_, T> {
98100
fn drop(&mut self) {
99-
drop(self.inner.take());
101+
// SAFETY: guard is dropped exactly once, here.
102+
unsafe { ManuallyDrop::drop(&mut self.inner) };
100103

101104
self.mut_condition.notify_one();
102105
self.immut_condition.notify_all();

0 commit comments

Comments
 (0)