File tree Expand file tree Collapse file tree 1 file changed +10
-2
lines changed
Expand file tree Collapse file tree 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> {
218218
219219 /// Swap the value out.
220220 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+ } ;
223227
224228 if old_value. is_null ( ) {
225229 None
226230 } 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.
227235 Some ( unsafe { Box :: from_raw ( old_value) } )
228236 }
229237 }
You can’t perform that action at this time.
0 commit comments