5
5
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
6
*/
7
7
8
+ use std:: mem:: ManuallyDrop ;
8
9
use std:: ops:: { Deref , DerefMut } ;
9
10
use std:: sync:: { Arc , Condvar , Mutex } ;
10
11
@@ -16,7 +17,7 @@ use crate::guards::{MutGuard, RefGuard};
16
17
/// See [`panicking::RefGuard`](crate::panicking::RefGuard) for more details.
17
18
#[ derive( Debug ) ]
18
19
pub struct RefGuardBlocking < ' a , T > {
19
- inner : Option < RefGuard < ' a , T > > ,
20
+ inner : ManuallyDrop < RefGuard < ' a , T > > ,
20
21
mut_condition : Arc < Condvar > ,
21
22
state : Arc < Mutex < ThreadTracker > > ,
22
23
}
@@ -28,7 +29,7 @@ impl<'a, T> RefGuardBlocking<'a, T> {
28
29
state : Arc < Mutex < ThreadTracker > > ,
29
30
) -> Self {
30
31
Self {
31
- inner : Some ( inner) ,
32
+ inner : ManuallyDrop :: new ( inner) ,
32
33
mut_condition,
33
34
state,
34
35
}
@@ -39,7 +40,7 @@ impl<'a, T> Deref for RefGuardBlocking<'a, T> {
39
40
type Target = <RefGuard < ' a , T > as Deref >:: Target ;
40
41
41
42
fn deref ( & self ) -> & Self :: Target {
42
- self . inner . as_ref ( ) . unwrap ( ) . deref ( )
43
+ self . inner . deref ( ) . deref ( )
43
44
}
44
45
}
45
46
@@ -49,7 +50,8 @@ impl<T> Drop for RefGuardBlocking<'_, T> {
49
50
50
51
state_lock. decrement_current_thread_shared_count ( ) ;
51
52
52
- drop ( self . inner . take ( ) ) ;
53
+ // SAFETY: guard is dropped exactly once, here.
54
+ unsafe { ManuallyDrop :: drop ( & mut self . inner ) } ;
53
55
54
56
self . mut_condition . notify_one ( ) ;
55
57
drop ( state_lock) ;
@@ -61,7 +63,7 @@ impl<T> Drop for RefGuardBlocking<'_, T> {
61
63
/// See [`panicking::MutGuard`](crate::panicking::MutGuard) for more details.
62
64
#[ derive( Debug ) ]
63
65
pub struct MutGuardBlocking < ' a , T > {
64
- inner : Option < MutGuard < ' a , T > > ,
66
+ inner : ManuallyDrop < MutGuard < ' a , T > > ,
65
67
mut_condition : Arc < Condvar > ,
66
68
immut_condition : Arc < Condvar > ,
67
69
}
@@ -73,7 +75,7 @@ impl<'a, T> MutGuardBlocking<'a, T> {
73
75
immut_condition : Arc < Condvar > ,
74
76
) -> Self {
75
77
Self {
76
- inner : Some ( inner) ,
78
+ inner : ManuallyDrop :: new ( inner) ,
77
79
immut_condition,
78
80
mut_condition,
79
81
}
@@ -84,19 +86,20 @@ impl<'a, T> Deref for MutGuardBlocking<'a, T> {
84
86
type Target = <MutGuard < ' a , T > as Deref >:: Target ;
85
87
86
88
fn deref ( & self ) -> & Self :: Target {
87
- self . inner . as_ref ( ) . unwrap ( ) . deref ( )
89
+ self . inner . deref ( ) . deref ( )
88
90
}
89
91
}
90
92
91
93
impl < T > DerefMut for MutGuardBlocking < ' _ , T > {
92
94
fn deref_mut ( & mut self ) -> & mut Self :: Target {
93
- self . inner . as_mut ( ) . unwrap ( ) . deref_mut ( )
95
+ self . inner . deref_mut ( ) . deref_mut ( )
94
96
}
95
97
}
96
98
97
99
impl < T > Drop for MutGuardBlocking < ' _ , T > {
98
100
fn drop ( & mut self ) {
99
- drop ( self . inner . take ( ) ) ;
101
+ // SAFETY: guard is dropped exactly once, here.
102
+ unsafe { ManuallyDrop :: drop ( & mut self . inner ) } ;
100
103
101
104
self . mut_condition . notify_one ( ) ;
102
105
self . immut_condition . notify_all ( ) ;
0 commit comments