Make Arc::make_unique check weak refs; add make_unique to Rc
This patch makes `Arc::make_unique` examine the number of weak references as well as strong references, which is required for safety. It also adds a `make_unique` method to the `Rc` type for consistency. Closes #14521.
This commit is contained in:
@@ -152,7 +152,11 @@ impl<T: Send + Share + Clone> Arc<T> {
|
||||
#[inline]
|
||||
#[experimental]
|
||||
pub fn make_unique<'a>(&'a mut self) -> &'a mut T {
|
||||
if self.inner().strong.load(atomics::SeqCst) != 1 {
|
||||
// Note that we hold a strong reference, which also counts as
|
||||
// a weak reference, so we only clone if there is an
|
||||
// additional reference of either kind.
|
||||
if self.inner().strong.load(atomics::SeqCst) != 1 ||
|
||||
self.inner().weak.load(atomics::SeqCst) != 1 {
|
||||
*self = Arc::new(self.deref().clone())
|
||||
}
|
||||
// This unsafety is ok because we're guaranteed that the pointer
|
||||
@@ -356,6 +360,20 @@ mod tests {
|
||||
assert!(*cow1 == *cow2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cowarc_clone_weak() {
|
||||
let mut cow0 = Arc::new(75u);
|
||||
let cow1_weak = cow0.downgrade();
|
||||
|
||||
assert!(75 == *cow0);
|
||||
assert!(75 == *cow1_weak.upgrade().unwrap());
|
||||
|
||||
*cow0.make_unique() += 1;
|
||||
|
||||
assert!(76 == *cow0);
|
||||
assert!(cow1_weak.upgrade().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_live() {
|
||||
let x = Arc::new(5);
|
||||
|
||||
Reference in New Issue
Block a user