File tree 1 file changed +10
-2
lines changed
1 file changed +10
-2
lines changed Original file line number Diff line number Diff line change @@ -218,12 +218,20 @@ impl<T> AtomicCell<T> {
218
218
219
219
/// Swap the value out.
220
220
fn replace ( & self , value : Option < Box < T > > ) -> Option < Box < T > > {
221
- let value = value. map_or ( ptr:: null_mut ( ) , |value| Box :: into_raw ( value) ) ;
222
- let old_value = self . 0 . swap ( value, Ordering :: SeqCst ) ;
221
+ let old_value = match value {
222
+ Some ( value) => self . 0 . swap ( Box :: into_raw ( value) , Ordering :: AcqRel ) ,
223
+ // Acquire is needed to synchronize with the store of a non-null ptr, but since a null ptr
224
+ // will never be dereferenced, there is no need to synchronize the store of a null ptr.
225
+ None => self . 0 . swap ( ptr:: null_mut ( ) , Ordering :: Acquire ) ,
226
+ } ;
223
227
224
228
if old_value. is_null ( ) {
225
229
None
226
230
} else {
231
+ // SAFETY:
232
+ // - AcqRel/Acquire ensures that it does not read a pointer to potentially invalid memory.
233
+ // - We've checked that old_value is not null.
234
+ // - We do not store invalid pointers other than null in self.0.
227
235
Some ( unsafe { Box :: from_raw ( old_value) } )
228
236
}
229
237
}
You can’t perform that action at this time.
0 commit comments