@@ -242,6 +242,38 @@ pub fn weak_count<T>(this: &Arc<T>) -> usize { this.inner().weak.load(SeqCst) -
242
242
#[ unstable( feature = "alloc" ) ]
243
243
pub fn strong_count < T > ( this : & Arc < T > ) -> usize { this. inner ( ) . strong . load ( SeqCst ) }
244
244
245
+
246
+ /// Try accessing a mutable reference to the contents behind an unique `Arc<T>`.
247
+ ///
248
+ /// The access is granted only if this is the only reference to the object.
249
+ /// Otherwise, `None` is returned.
250
+ ///
251
+ /// # Examples
252
+ ///
253
+ /// ```
254
+ /// # #![feature(alloc)]
255
+ /// use std::alloc::arc;
256
+ ///
257
+ /// let mut four = arc::Arc::new(4);
258
+ ///
259
+ /// arc::unique(&mut four).map(|num| *num = 5);
260
+ /// ```
261
+ #[ inline]
262
+ #[ unstable( feature = "alloc" ) ]
263
+ pub fn unique < T > ( this : & mut Arc < T > ) -> Option < & mut T > {
264
+ if strong_count ( this) == 1 && weak_count ( this) == 0 {
265
+ // This unsafety is ok because we're guaranteed that the pointer
266
+ // returned is the *only* pointer that will ever be returned to T. Our
267
+ // reference count is guaranteed to be 1 at this point, and we required
268
+ // the Arc itself to be `mut`, so we're returning the only possible
269
+ // reference to the inner data.
270
+ let inner = unsafe { & mut * * this. _ptr } ;
271
+ Some ( & mut inner. data )
272
+ } else {
273
+ None
274
+ }
275
+ }
276
+
245
277
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
246
278
impl < T > Clone for Arc < T > {
247
279
/// Makes a clone of the `Arc<T>`.
@@ -312,11 +344,8 @@ impl<T: Send + Sync + Clone> Arc<T> {
312
344
self . inner ( ) . weak . load ( SeqCst ) != 1 {
313
345
* self = Arc :: new ( ( * * self ) . clone ( ) )
314
346
}
315
- // This unsafety is ok because we're guaranteed that the pointer
316
- // returned is the *only* pointer that will ever be returned to T. Our
317
- // reference count is guaranteed to be 1 at this point, and we required
318
- // the Arc itself to be `mut`, so we're returning the only possible
319
- // reference to the inner data.
347
+ // As with `unique()`, the unsafety is ok because our reference was
348
+ // either unique to begin with, or became one upon cloning the contents.
320
349
let inner = unsafe { & mut * * self . _ptr } ;
321
350
& mut inner. data
322
351
}
@@ -659,7 +688,7 @@ mod tests {
659
688
use std:: sync:: atomic:: Ordering :: { Acquire , SeqCst } ;
660
689
use std:: thread;
661
690
use std:: vec:: Vec ;
662
- use super :: { Arc , Weak , weak_count, strong_count} ;
691
+ use super :: { Arc , Weak , weak_count, strong_count, unique } ;
663
692
use std:: sync:: Mutex ;
664
693
665
694
struct Canary ( * mut atomic:: AtomicUsize ) ;
@@ -695,6 +724,21 @@ mod tests {
695
724
assert_eq ! ( ( * arc_v) [ 4 ] , 5 ) ;
696
725
}
697
726
727
+ #[ test]
728
+ fn test_arc_unique ( ) {
729
+ let mut x = Arc :: new ( 10 ) ;
730
+ assert ! ( unique( & mut x) . is_some( ) ) ;
731
+ {
732
+ let y = x. clone ( ) ;
733
+ assert ! ( unique( & mut x) . is_none( ) ) ;
734
+ }
735
+ {
736
+ let z = x. downgrade ( ) ;
737
+ assert ! ( unique( & mut x) . is_none( ) ) ;
738
+ }
739
+ assert ! ( unique( & mut x) . is_some( ) ) ;
740
+ }
741
+
698
742
#[ test]
699
743
fn test_cowarc_clone_make_unique ( ) {
700
744
let mut cow0 = Arc :: new ( 75 ) ;
0 commit comments