From 49edaf14fd1ef0c190e67998ad299db67d19b739 Mon Sep 17 00:00:00 2001 From: Jacques-Henri Jourdan Date: Tue, 18 Jul 2017 19:31:22 +0200 Subject: [PATCH 1/2] Fix in weak_count in Arc. In the case the weak count was locked, the weak_count function could return usize::MAX. We need to test this condition manually. --- src/liballoc/arc.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index d9edf50b9c8ec..0205f3f3553e2 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -453,7 +453,10 @@ impl Arc { #[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. From 8416713240e11e898872f5028f927997f3754696 Mon Sep 17 00:00:00 2001 From: Jacques-Henri Jourdan Date: Thu, 20 Jul 2017 01:59:01 +0200 Subject: [PATCH 2/2] Add test test_weak_count_locked --- src/liballoc/arc.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 0205f3f3553e2..85c7efb7ac50c 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -1501,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")]