@@ -3,6 +3,7 @@ use crate::sync::{AtomicBool, ReadGuard, RwLock, WriteGuard};
3
3
use crate :: sync:: { DynSend , DynSync } ;
4
4
use std:: {
5
5
cell:: UnsafeCell ,
6
+ marker:: PhantomData ,
6
7
ops:: { Deref , DerefMut } ,
7
8
sync:: atomic:: Ordering ,
8
9
} ;
@@ -37,10 +38,7 @@ impl<T> FreezeLock<T> {
37
38
} else {
38
39
Some ( self . lock . read ( ) )
39
40
} ,
40
- // SAFETY: If this is not frozen, `_lock_guard` holds the lock to the `UnsafeCell` so
41
- // this has shared access until the `FreezeReadGuard` is dropped. If this is frozen,
42
- // the data cannot be modified and shared access is sound.
43
- data : unsafe { & * self . data . get ( ) } ,
41
+ lock : self ,
44
42
}
45
43
}
46
44
@@ -50,12 +48,7 @@ impl<T> FreezeLock<T> {
50
48
let _lock_guard = self . lock . write ( ) ;
51
49
// Use relaxed ordering since we're in the write lock.
52
50
assert ! ( !self . frozen. load( Ordering :: Relaxed ) , "still mutable" ) ;
53
- FreezeWriteGuard {
54
- _lock_guard,
55
- // SAFETY: `_lock_guard` holds the lock to the `UnsafeCell` so this has mutable access
56
- // until the `FreezeWriteGuard` is dropped.
57
- data : unsafe { & mut * self . data . get ( ) } ,
58
- }
51
+ FreezeWriteGuard { _lock_guard, lock : self , marker : PhantomData }
59
52
}
60
53
61
54
#[ inline]
@@ -75,35 +68,41 @@ impl<T> FreezeLock<T> {
75
68
#[ must_use = "if unused the FreezeLock may immediately unlock" ]
76
69
pub struct FreezeReadGuard < ' a , T > {
77
70
_lock_guard : Option < ReadGuard < ' a , ( ) > > ,
78
- data : & ' a T ,
71
+ lock : & ' a FreezeLock < T > ,
79
72
}
80
73
81
74
impl < ' a , T : ' a > Deref for FreezeReadGuard < ' a , T > {
82
75
type Target = T ;
83
76
#[ inline]
84
77
fn deref ( & self ) -> & T {
85
- self . data
78
+ // SAFETY: If `lock` is not frozen, `_lock_guard` holds the lock to the `UnsafeCell` so
79
+ // this has shared access until the `FreezeReadGuard` is dropped. If `lock` is frozen,
80
+ // the data cannot be modified and shared access is sound.
81
+ unsafe { & * self . lock . data . get ( ) }
86
82
}
87
83
}
88
84
89
85
/// A guard holding mutable access to a `FreezeLock` which is in a locked state or frozen.
90
86
#[ must_use = "if unused the FreezeLock may immediately unlock" ]
91
87
pub struct FreezeWriteGuard < ' a , T > {
92
88
_lock_guard : WriteGuard < ' a , ( ) > ,
93
- data : & ' a mut T ,
89
+ lock : & ' a FreezeLock < T > ,
90
+ marker : PhantomData < & ' a mut T > ,
94
91
}
95
92
96
93
impl < ' a , T : ' a > Deref for FreezeWriteGuard < ' a , T > {
97
94
type Target = T ;
98
95
#[ inline]
99
96
fn deref ( & self ) -> & T {
100
- self . data
97
+ // SAFETY: `self._lock_guard` holds the lock to the `UnsafeCell` so this has shared access.
98
+ unsafe { & * self . lock . data . get ( ) }
101
99
}
102
100
}
103
101
104
102
impl < ' a , T : ' a > DerefMut for FreezeWriteGuard < ' a , T > {
105
103
#[ inline]
106
104
fn deref_mut ( & mut self ) -> & mut T {
107
- self . data
105
+ // SAFETY: `self._lock_guard` holds the lock to the `UnsafeCell` so this has mutable access.
106
+ unsafe { & mut * self . lock . data . get ( ) }
108
107
}
109
108
}
0 commit comments