@@ -6,6 +6,7 @@ use std::{
66 intrinsics:: likely,
77 marker:: PhantomData ,
88 ops:: { Deref , DerefMut } ,
9+ ptr:: NonNull ,
910 sync:: atomic:: Ordering ,
1011} ;
1112
@@ -79,7 +80,7 @@ impl<T> FreezeLock<T> {
7980 } else {
8081 Some ( self . lock . read ( ) )
8182 } ,
82- lock : self ,
83+ data : unsafe { NonNull :: new_unchecked ( self . data . get ( ) ) } ,
8384 }
8485 }
8586
@@ -101,7 +102,12 @@ impl<T> FreezeLock<T> {
101102 if self . frozen . load ( Ordering :: Relaxed ) {
102103 None
103104 } else {
104- Some ( FreezeWriteGuard { _lock_guard, lock : self , marker : PhantomData } )
105+ Some ( FreezeWriteGuard {
106+ _lock_guard,
107+ data : unsafe { NonNull :: new_unchecked ( self . data . get ( ) ) } ,
108+ frozen : & self . frozen ,
109+ marker : PhantomData ,
110+ } )
105111 }
106112 }
107113
@@ -120,52 +126,75 @@ impl<T> FreezeLock<T> {
120126
121127/// A guard holding shared access to a `FreezeLock` which is in a locked state or frozen.
122128#[ must_use = "if unused the FreezeLock may immediately unlock" ]
123- pub struct FreezeReadGuard < ' a , T > {
129+ pub struct FreezeReadGuard < ' a , T : ? Sized > {
124130 _lock_guard : Option < ReadGuard < ' a , ( ) > > ,
125- lock : & ' a FreezeLock < T > ,
131+ data : NonNull < T > ,
126132}
127133
128- impl < ' a , T : ' a > Deref for FreezeReadGuard < ' a , T > {
134+ impl < ' a , T : ? Sized + ' a > Deref for FreezeReadGuard < ' a , T > {
129135 type Target = T ;
130136 #[ inline]
131137 fn deref ( & self ) -> & T {
132- // SAFETY: If ` lock` is not frozen, `_lock_guard` holds the lock to the `UnsafeCell` so
133- // this has shared access until the `FreezeReadGuard` is dropped. If ` lock` is frozen,
138+ // SAFETY: If the lock is not frozen, `_lock_guard` holds the lock to the `UnsafeCell` so
139+ // this has shared access until the `FreezeReadGuard` is dropped. If the lock is frozen,
134140 // the data cannot be modified and shared access is sound.
135- unsafe { & * self . lock . data . get ( ) }
141+ unsafe { & * self . data . as_ptr ( ) }
142+ }
143+ }
144+
145+ impl < ' a , T : ?Sized > FreezeReadGuard < ' a , T > {
146+ #[ inline]
147+ pub fn map < U : ?Sized > ( this : Self , f : impl FnOnce ( & T ) -> & U ) -> FreezeReadGuard < ' a , U > {
148+ FreezeReadGuard { data : NonNull :: from ( f ( & * this) ) , _lock_guard : this. _lock_guard }
136149 }
137150}
138151
139152/// A guard holding mutable access to a `FreezeLock` which is in a locked state or frozen.
140153#[ must_use = "if unused the FreezeLock may immediately unlock" ]
141- pub struct FreezeWriteGuard < ' a , T > {
154+ pub struct FreezeWriteGuard < ' a , T : ? Sized > {
142155 _lock_guard : WriteGuard < ' a , ( ) > ,
143- lock : & ' a FreezeLock < T > ,
156+ frozen : & ' a AtomicBool ,
157+ data : NonNull < T > ,
144158 marker : PhantomData < & ' a mut T > ,
145159}
146160
147161impl < ' a , T > FreezeWriteGuard < ' a , T > {
148162 pub fn freeze ( self ) -> & ' a T {
149- self . lock . frozen . store ( true , Ordering :: Release ) ;
163+ self . frozen . store ( true , Ordering :: Release ) ;
150164
151165 // SAFETY: This is frozen so the data cannot be modified and shared access is sound.
152- unsafe { & * self . lock . data . get ( ) }
166+ unsafe { & * self . data . as_ptr ( ) }
167+ }
168+ }
169+
170+ impl < ' a , T : ?Sized > FreezeWriteGuard < ' a , T > {
171+ #[ inline]
172+ pub fn map < U : ?Sized > (
173+ mut this : Self ,
174+ f : impl FnOnce ( & mut T ) -> & mut U ,
175+ ) -> FreezeWriteGuard < ' a , U > {
176+ FreezeWriteGuard {
177+ data : NonNull :: from ( f ( & mut * this) ) ,
178+ _lock_guard : this. _lock_guard ,
179+ frozen : this. frozen ,
180+ marker : PhantomData ,
181+ }
153182 }
154183}
155184
156- impl < ' a , T : ' a > Deref for FreezeWriteGuard < ' a , T > {
185+ impl < ' a , T : ? Sized + ' a > Deref for FreezeWriteGuard < ' a , T > {
157186 type Target = T ;
158187 #[ inline]
159188 fn deref ( & self ) -> & T {
160189 // SAFETY: `self._lock_guard` holds the lock to the `UnsafeCell` so this has shared access.
161- unsafe { & * self . lock . data . get ( ) }
190+ unsafe { & * self . data . as_ptr ( ) }
162191 }
163192}
164193
165- impl < ' a , T : ' a > DerefMut for FreezeWriteGuard < ' a , T > {
194+ impl < ' a , T : ? Sized + ' a > DerefMut for FreezeWriteGuard < ' a , T > {
166195 #[ inline]
167196 fn deref_mut ( & mut self ) -> & mut T {
168197 // SAFETY: `self._lock_guard` holds the lock to the `UnsafeCell` so this has mutable access.
169- unsafe { & mut * self . lock . data . get ( ) }
198+ unsafe { & mut * self . data . as_ptr ( ) }
170199 }
171200}
0 commit comments