Skip to content

Commit

Permalink
Auto merge of #43318 - jhjourdan:jh/fix_weak_cound_MAX, r=alexcrichton
Browse files Browse the repository at this point in the history
Fix in weak_count in Arc in the case the weak count is locked.

In the case the weak count was locked, the weak_count function could
return usize::MAX. We need to test this condition manually.
  • Loading branch information
bors committed Jul 21, 2017
2 parents e3c8433 + 8416713 commit d361efa
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,10 @@ impl<T: ?Sized> Arc<T> {
#[inline]
#[stable(feature = "arc_counts", since = "1.15.0")]
pub fn weak_count(this: &Self) -> usize {
this.inner().weak.load(SeqCst) - 1
let cnt = this.inner().weak.load(SeqCst);
// If the weak count is currently locked, the value of the
// count was 0 just before taking the lock.
if cnt == usize::MAX { 0 } else { cnt - 1 }
}

/// Gets the number of strong (`Arc`) pointers to this value.
Expand Down Expand Up @@ -1498,6 +1501,25 @@ mod tests {
assert!(Arc::ptr_eq(&five, &same_five));
assert!(!Arc::ptr_eq(&five, &other_five));
}

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_weak_count_locked() {
let mut a = Arc::new(atomic::AtomicBool::new(false));
let a2 = a.clone();
let t = thread::spawn(move || {
for _i in 0..1000000 {
Arc::get_mut(&mut a);
}
a.store(true, SeqCst);
});

while !a2.load(SeqCst) {
let n = Arc::weak_count(&a2);
assert!(n < 2, "bad weak count: {}", n);
}
t.join().unwrap();
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down

0 comments on commit d361efa

Please sign in to comment.