From 7cae633b29a3500eb88400624c58435357464530 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Sat, 12 Nov 2022 00:02:58 +0100 Subject: [PATCH] Fix `Arc` incorrectly initializing itself as `Rc` --- narcissus-core/src/ref_count.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/narcissus-core/src/ref_count.rs b/narcissus-core/src/ref_count.rs index 5408b35..35ea1d2 100644 --- a/narcissus-core/src/ref_count.rs +++ b/narcissus-core/src/ref_count.rs @@ -21,6 +21,14 @@ impl Inner { value, } } + + #[inline] + fn new_atomic(value: T) -> Self { + Self { + strong: AtomicI32::new(1), + value, + } + } } impl Inner { @@ -188,7 +196,7 @@ unsafe impl Sync for Arc {} impl Arc { pub fn new(value: T) -> Self { - Self::from_inner(Box::leak(Box::new(Inner::new(value))).into()) + Self::from_inner(Box::leak(Box::new(Inner::new_atomic(value))).into()) } } @@ -301,6 +309,28 @@ impl Deref for Arc { mod tests { use crate::*; + #[test] + fn rc_drop() { + use std::sync::atomic::{AtomicU32, Ordering}; + + struct A<'a>(&'a AtomicU32); + impl<'a> Drop for A<'a> { + fn drop(&mut self) { + self.0.fetch_add(1, Ordering::SeqCst); + } + } + + let counter = AtomicU32::new(0); + let a = Arc::new(A(&counter)); + assert_eq!(counter.load(Ordering::Relaxed), 0); + let b = a.clone(); + assert_eq!(counter.load(Ordering::Relaxed), 0); + drop(a); + assert_eq!(counter.load(Ordering::Relaxed), 0); + drop(b); + assert_eq!(counter.load(Ordering::Relaxed), 1); + } + #[test] fn rc_double_upgrade() { let rc1 = Rc::new(()); -- 2.49.0