Skip to content

Commit d66c0b0

Browse files
committed
stablize weak pointers and uniqueness ops on Arc
1 parent b9c0fe7 commit d66c0b0

File tree

1 file changed

+44
-50
lines changed

1 file changed

+44
-50
lines changed

src/liballoc/arc.rs

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
136136
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
137137
/// used to break cycles between `Arc` pointers.
138138
#[unsafe_no_drop_flag]
139-
#[unstable(feature = "arc_weak",
140-
reason = "Weak pointers may not belong in this module.")]
139+
#[stable(feature = "arc_weak", since = "1.4.0")]
141140
pub struct Weak<T: ?Sized> {
142141
// FIXME #12808: strange name to try to avoid interfering with
143142
// field accesses of the contained type via Deref
@@ -161,7 +160,7 @@ struct ArcInner<T: ?Sized> {
161160

162161
// the value usize::MAX acts as a sentinel for temporarily "locking" the
163162
// ability to upgrade weak pointers or downgrade strong ones; this is used
164-
// to avoid races in `make_unique` and `get_mut`.
163+
// to avoid races in `make_mut` and `get_mut`.
165164
weak: atomic::AtomicUsize,
166165

167166
data: T,
@@ -200,16 +199,13 @@ impl<T: ?Sized> Arc<T> {
200199
/// # Examples
201200
///
202201
/// ```
203-
/// #![feature(arc_weak)]
204-
///
205202
/// use std::sync::Arc;
206203
///
207204
/// let five = Arc::new(5);
208205
///
209206
/// let weak_five = five.downgrade();
210207
/// ```
211-
#[unstable(feature = "arc_weak",
212-
reason = "Weak pointers may not belong in this module.")]
208+
#[stable(feature = "arc_weak", since = "1.4.0")]
213209
pub fn downgrade(&self) -> Weak<T> {
214210
loop {
215211
// This Relaxed is OK because we're checking the value in the CAS
@@ -234,14 +230,14 @@ impl<T: ?Sized> Arc<T> {
234230

235231
/// Get the number of weak references to this value.
236232
#[inline]
237-
#[unstable(feature = "arc_counts")]
233+
#[unstable(feature = "arc_counts", reason = "not clearly useful, and racy", issue = "27718")]
238234
pub fn weak_count(this: &Arc<T>) -> usize {
239235
this.inner().weak.load(SeqCst) - 1
240236
}
241237

242238
/// Get the number of strong references to this value.
243239
#[inline]
244-
#[unstable(feature = "arc_counts")]
240+
#[unstable(feature = "arc_counts", reason = "not clearly useful, and racy", issue = "27718")]
245241
pub fn strong_count(this: &Arc<T>) -> usize {
246242
this.inner().strong.load(SeqCst)
247243
}
@@ -330,27 +326,40 @@ impl<T: ?Sized> Deref for Arc<T> {
330326
}
331327

332328
impl<T: Clone> Arc<T> {
333-
/// Make a mutable reference from the given `Arc<T>`.
329+
330+
#[unstable(feature = "renamed_arc_unique", reason = "renamed to make_mut", issue = "27718")]
331+
#[deprecated(since = "1.4.0", reason = "renamed to make_mut")]
332+
pub fn make_unique(this: &mut Arc<T>) -> &mut T {
333+
Arc::make_mut(this)
334+
}
335+
336+
/// Make a mutable reference into the given `Arc<T>` by cloning the inner
337+
/// data if the `Arc<T>` doesn't have one strong reference and no weak
338+
/// references.
334339
///
335-
/// This is also referred to as a copy-on-write operation because the inner
336-
/// data is cloned if the (strong) reference count is greater than one. If
337-
/// we hold the only strong reference, any existing weak references will no
338-
/// longer be upgradeable.
340+
/// This is also referred to as a copy-on-write.
339341
///
340342
/// # Examples
341343
///
342344
/// ```
343-
/// #![feature(arc_unique)]
344-
///
345345
/// use std::sync::Arc;
346346
///
347-
/// let mut five = Arc::new(5);
347+
/// let mut data = Arc::new(5);
348+
///
349+
/// *data.make_mut() += 1; // Won't clone anything
350+
/// let mut other_data = data.clone(); // Won't clone inner data
351+
/// *data.make_mut() += 1; // Clones inner data
352+
/// *data.make_mut() += 1; // Won't clone anything
353+
/// *other_data.make_mut() *= 2; // Won't clone anything
354+
///
355+
/// // Note: data and other_data now point to different numbers
356+
/// assert_eq!(*data, 8);
357+
/// assert_eq!(*other_data, 12);
348358
///
349-
/// let mut_five = Arc::make_unique(&mut five);
350359
/// ```
351360
#[inline]
352-
#[unstable(feature = "arc_unique")]
353-
pub fn make_unique(this: &mut Arc<T>) -> &mut T {
361+
#[stable(feature = "arc_unique", since = "1.4.0")]
362+
pub fn make_mut(this: &mut Arc<T>) -> &mut T {
354363
// Note that we hold both a strong reference and a weak reference.
355364
// Thus, releasing our strong reference only will not, by itself, cause
356365
// the memory to be deallocated.
@@ -405,29 +414,23 @@ impl<T: Clone> Arc<T> {
405414
}
406415

407416
impl<T: ?Sized> Arc<T> {
408-
/// Returns a mutable reference to the contained value if the `Arc<T>` is unique.
409-
///
410-
/// Returns `None` if the `Arc<T>` is not unique.
417+
/// Returns a mutable reference to the contained value if the `Arc<T>` has
418+
/// one strong reference and no weak references.
411419
///
412420
/// # Examples
413421
///
414422
/// ```
415-
/// #![feature(arc_unique, alloc)]
416-
///
417-
/// extern crate alloc;
418-
/// # fn main() {
419-
/// use alloc::arc::Arc;
423+
/// use std::sync::Arc;
420424
///
421425
/// let mut x = Arc::new(3);
422426
/// *Arc::get_mut(&mut x).unwrap() = 4;
423427
/// assert_eq!(*x, 4);
424428
///
425429
/// let _y = x.clone();
426430
/// assert!(Arc::get_mut(&mut x).is_none());
427-
/// # }
428431
/// ```
429432
#[inline]
430-
#[unstable(feature = "arc_unique")]
433+
#[stable(feature = "arc_unique", since = "1.4.0")]
431434
pub fn get_mut(this: &mut Arc<T>) -> Option<&mut T> {
432435
if this.is_unique() {
433436
// This unsafety is ok because we're guaranteed that the pointer
@@ -540,8 +543,6 @@ impl<T: ?Sized> Drop for Arc<T> {
540543
}
541544
}
542545

543-
#[unstable(feature = "arc_weak",
544-
reason = "Weak pointers may not belong in this module.")]
545546
impl<T: ?Sized> Weak<T> {
546547
/// Upgrades a weak reference to a strong reference.
547548
///
@@ -553,8 +554,6 @@ impl<T: ?Sized> Weak<T> {
553554
/// # Examples
554555
///
555556
/// ```
556-
/// #![feature(arc_weak)]
557-
///
558557
/// use std::sync::Arc;
559558
///
560559
/// let five = Arc::new(5);
@@ -563,6 +562,7 @@ impl<T: ?Sized> Weak<T> {
563562
///
564563
/// let strong_five: Option<Arc<_>> = weak_five.upgrade();
565564
/// ```
565+
#[stable(feature = "arc_weak", since = "1.4.0")]
566566
pub fn upgrade(&self) -> Option<Arc<T>> {
567567
// We use a CAS loop to increment the strong count instead of a
568568
// fetch_add because once the count hits 0 it must never be above 0.
@@ -588,8 +588,7 @@ impl<T: ?Sized> Weak<T> {
588588
}
589589
}
590590

591-
#[unstable(feature = "arc_weak",
592-
reason = "Weak pointers may not belong in this module.")]
591+
#[stable(feature = "arc_weak", since = "1.4.0")]
593592
impl<T: ?Sized> Clone for Weak<T> {
594593
/// Makes a clone of the `Weak<T>`.
595594
///
@@ -598,8 +597,6 @@ impl<T: ?Sized> Clone for Weak<T> {
598597
/// # Examples
599598
///
600599
/// ```
601-
/// #![feature(arc_weak)]
602-
///
603600
/// use std::sync::Arc;
604601
///
605602
/// let weak_five = Arc::new(5).downgrade();
@@ -632,8 +629,6 @@ impl<T: ?Sized> Drop for Weak<T> {
632629
/// # Examples
633630
///
634631
/// ```
635-
/// #![feature(arc_weak)]
636-
///
637632
/// use std::sync::Arc;
638633
///
639634
/// {
@@ -891,18 +886,18 @@ mod tests {
891886
}
892887

893888
#[test]
894-
fn test_cowarc_clone_make_unique() {
889+
fn test_cowarc_clone_make_mut() {
895890
let mut cow0 = Arc::new(75);
896891
let mut cow1 = cow0.clone();
897892
let mut cow2 = cow1.clone();
898893

899-
assert!(75 == *Arc::make_unique(&mut cow0));
900-
assert!(75 == *Arc::make_unique(&mut cow1));
901-
assert!(75 == *Arc::make_unique(&mut cow2));
894+
assert!(75 == *Arc::make_mut(&mut cow0));
895+
assert!(75 == *Arc::make_mut(&mut cow1));
896+
assert!(75 == *Arc::make_mut(&mut cow2));
902897

903-
*Arc::make_unique(&mut cow0) += 1;
904-
*Arc::make_unique(&mut cow1) += 2;
905-
*Arc::make_unique(&mut cow2) += 3;
898+
*Arc::make_mut(&mut cow0) += 1;
899+
*Arc::make_mut(&mut cow1) += 2;
900+
*Arc::make_mut(&mut cow2) += 3;
906901

907902
assert!(76 == *cow0);
908903
assert!(77 == *cow1);
@@ -924,8 +919,7 @@ mod tests {
924919
assert!(75 == *cow1);
925920
assert!(75 == *cow2);
926921

927-
*Arc::make_unique(&mut cow0) += 1;
928-
922+
*Arc::make_mut(&mut cow0) += 1;
929923
assert!(76 == *cow0);
930924
assert!(75 == *cow1);
931925
assert!(75 == *cow2);
@@ -945,7 +939,7 @@ mod tests {
945939
assert!(75 == *cow0);
946940
assert!(75 == *cow1_weak.upgrade().unwrap());
947941

948-
*Arc::make_unique(&mut cow0) += 1;
942+
*Arc::make_mut(&mut cow0) += 1;
949943

950944
assert!(76 == *cow0);
951945
assert!(cow1_weak.upgrade().is_none());

0 commit comments

Comments
 (0)