@@ -250,6 +250,9 @@ pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.loa
250
250
///
251
251
/// Returns `None` if the `Arc<T>` is not unique.
252
252
///
253
+ /// This function is marked **unsafe** because it is racy if weak pointers
254
+ /// are active.
255
+ ///
253
256
/// # Examples
254
257
///
255
258
/// ```
@@ -258,24 +261,27 @@ pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.loa
258
261
/// # fn main() {
259
262
/// use alloc::arc::{Arc, get_mut};
260
263
///
264
+ /// # unsafe {
261
265
/// let mut x = Arc::new(3);
262
266
/// *get_mut(&mut x).unwrap() = 4;
263
267
/// assert_eq!(*x, 4);
264
268
///
265
269
/// let _y = x.clone();
266
270
/// assert!(get_mut(&mut x).is_none());
267
271
/// # }
272
+ /// # }
268
273
/// ```
269
274
#[ inline]
270
275
#[ unstable( feature = "alloc" ) ]
271
- pub fn get_mut < T : ?Sized > ( this : & mut Arc < T > ) -> Option < & mut T > {
276
+ pub unsafe fn get_mut < T : ?Sized > ( this : & mut Arc < T > ) -> Option < & mut T > {
277
+ // FIXME(#24880) potential race with upgraded weak pointers here
272
278
if strong_count ( this) == 1 && weak_count ( this) == 0 {
273
279
// This unsafety is ok because we're guaranteed that the pointer
274
280
// returned is the *only* pointer that will ever be returned to T. Our
275
281
// reference count is guaranteed to be 1 at this point, and we required
276
282
// the Arc itself to be `mut`, so we're returning the only possible
277
283
// reference to the inner data.
278
- let inner = unsafe { & mut * * this. _ptr } ;
284
+ let inner = & mut * * this. _ptr ;
279
285
Some ( & mut inner. data )
280
286
} else {
281
287
None
@@ -332,19 +338,26 @@ impl<T: Clone> Arc<T> {
332
338
/// This is also referred to as a copy-on-write operation because the inner
333
339
/// data is cloned if the reference count is greater than one.
334
340
///
341
+ /// This method is marked **unsafe** because it is racy if weak pointers
342
+ /// are active.
343
+ ///
335
344
/// # Examples
336
345
///
337
346
/// ```
338
347
/// # #![feature(alloc)]
339
348
/// use std::sync::Arc;
340
349
///
350
+ /// # unsafe {
341
351
/// let mut five = Arc::new(5);
342
352
///
343
353
/// let mut_five = five.make_unique();
354
+ /// # }
344
355
/// ```
345
356
#[ inline]
346
357
#[ unstable( feature = "alloc" ) ]
347
- pub fn make_unique ( & mut self ) -> & mut T {
358
+ pub unsafe fn make_unique ( & mut self ) -> & mut T {
359
+ // FIXME(#24880) potential race with upgraded weak pointers here
360
+ //
348
361
// Note that we hold a strong reference, which also counts as a weak
349
362
// reference, so we only clone if there is an additional reference of
350
363
// either kind.
@@ -354,7 +367,7 @@ impl<T: Clone> Arc<T> {
354
367
}
355
368
// As with `get_mut()`, the unsafety is ok because our reference was
356
369
// either unique to begin with, or became one upon cloning the contents.
357
- let inner = unsafe { & mut * * self . _ptr } ;
370
+ let inner = & mut * * self . _ptr ;
358
371
& mut inner. data
359
372
}
360
373
}
@@ -744,39 +757,43 @@ mod tests {
744
757
745
758
#[ test]
746
759
fn test_arc_get_mut ( ) {
747
- let mut x = Arc :: new ( 3 ) ;
748
- * get_mut ( & mut x) . unwrap ( ) = 4 ;
749
- assert_eq ! ( * x, 4 ) ;
750
- let y = x. clone ( ) ;
751
- assert ! ( get_mut( & mut x) . is_none( ) ) ;
752
- drop ( y) ;
753
- assert ! ( get_mut( & mut x) . is_some( ) ) ;
754
- let _w = x. downgrade ( ) ;
755
- assert ! ( get_mut( & mut x) . is_none( ) ) ;
760
+ unsafe {
761
+ let mut x = Arc :: new ( 3 ) ;
762
+ * get_mut ( & mut x) . unwrap ( ) = 4 ;
763
+ assert_eq ! ( * x, 4 ) ;
764
+ let y = x. clone ( ) ;
765
+ assert ! ( get_mut( & mut x) . is_none( ) ) ;
766
+ drop ( y) ;
767
+ assert ! ( get_mut( & mut x) . is_some( ) ) ;
768
+ let _w = x. downgrade ( ) ;
769
+ assert ! ( get_mut( & mut x) . is_none( ) ) ;
770
+ }
756
771
}
757
772
758
773
#[ test]
759
774
fn test_cowarc_clone_make_unique ( ) {
760
- let mut cow0 = Arc :: new ( 75 ) ;
761
- let mut cow1 = cow0. clone ( ) ;
762
- let mut cow2 = cow1. clone ( ) ;
763
-
764
- assert ! ( 75 == * cow0. make_unique( ) ) ;
765
- assert ! ( 75 == * cow1. make_unique( ) ) ;
766
- assert ! ( 75 == * cow2. make_unique( ) ) ;
767
-
768
- * cow0. make_unique ( ) += 1 ;
769
- * cow1. make_unique ( ) += 2 ;
770
- * cow2. make_unique ( ) += 3 ;
771
-
772
- assert ! ( 76 == * cow0) ;
773
- assert ! ( 77 == * cow1) ;
774
- assert ! ( 78 == * cow2) ;
775
-
776
- // none should point to the same backing memory
777
- assert ! ( * cow0 != * cow1) ;
778
- assert ! ( * cow0 != * cow2) ;
779
- assert ! ( * cow1 != * cow2) ;
775
+ unsafe {
776
+ let mut cow0 = Arc :: new ( 75 ) ;
777
+ let mut cow1 = cow0. clone ( ) ;
778
+ let mut cow2 = cow1. clone ( ) ;
779
+
780
+ assert ! ( 75 == * cow0. make_unique( ) ) ;
781
+ assert ! ( 75 == * cow1. make_unique( ) ) ;
782
+ assert ! ( 75 == * cow2. make_unique( ) ) ;
783
+
784
+ * cow0. make_unique ( ) += 1 ;
785
+ * cow1. make_unique ( ) += 2 ;
786
+ * cow2. make_unique ( ) += 3 ;
787
+
788
+ assert ! ( 76 == * cow0) ;
789
+ assert ! ( 77 == * cow1) ;
790
+ assert ! ( 78 == * cow2) ;
791
+
792
+ // none should point to the same backing memory
793
+ assert ! ( * cow0 != * cow1) ;
794
+ assert ! ( * cow0 != * cow2) ;
795
+ assert ! ( * cow1 != * cow2) ;
796
+ }
780
797
}
781
798
782
799
#[ test]
@@ -789,7 +806,9 @@ mod tests {
789
806
assert ! ( 75 == * cow1) ;
790
807
assert ! ( 75 == * cow2) ;
791
808
792
- * cow0. make_unique ( ) += 1 ;
809
+ unsafe {
810
+ * cow0. make_unique ( ) += 1 ;
811
+ }
793
812
794
813
assert ! ( 76 == * cow0) ;
795
814
assert ! ( 75 == * cow1) ;
@@ -810,7 +829,9 @@ mod tests {
810
829
assert ! ( 75 == * cow0) ;
811
830
assert ! ( 75 == * cow1_weak. upgrade( ) . unwrap( ) ) ;
812
831
813
- * cow0. make_unique ( ) += 1 ;
832
+ unsafe {
833
+ * cow0. make_unique ( ) += 1 ;
834
+ }
814
835
815
836
assert ! ( 76 == * cow0) ;
816
837
assert ! ( cow1_weak. upgrade( ) . is_none( ) ) ;
0 commit comments