Skip to content

Commit b95d96b

Browse files
committed
cc: add strong_count and weak_count exposing internal ref counts
Match related std::rc::Rc APIs.
1 parent d1244d2 commit b95d96b

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/cc.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ impl<T: ?Sized, O: AbstractObjectSpace> RawCc<T, O> {
371371
});
372372
RawWeak(self.0)
373373
}
374+
375+
/// Gets the reference count not considering weak references.
376+
#[inline]
377+
pub fn strong_count(&self) -> usize {
378+
self.ref_count()
379+
}
374380
}
375381

376382
impl<T: ?Sized, O: AbstractObjectSpace> RawWeak<T, O> {
@@ -394,6 +400,18 @@ impl<T: ?Sized, O: AbstractObjectSpace> RawWeak<T, O> {
394400
Some(RawCc(self.0))
395401
}
396402
}
403+
404+
/// Gets the reference count not considering weak references.
405+
#[inline]
406+
pub fn strong_count(&self) -> usize {
407+
self.inner().ref_count()
408+
}
409+
410+
/// Get the weak (non-owning) reference count.
411+
#[inline]
412+
pub fn weak_count(&self) -> usize {
413+
self.inner().weak_count()
414+
}
397415
}
398416

399417
impl<T: ?Sized, O: AbstractObjectSpace> RawCc<T, O> {
@@ -428,8 +446,9 @@ impl<T: ?Sized, O: AbstractObjectSpace> RawCc<T, O> {
428446
self.inner().ref_count()
429447
}
430448

449+
/// Get the weak (non-owning) reference count.
431450
#[inline]
432-
fn weak_count(&self) -> usize {
451+
pub fn weak_count(&self) -> usize {
433452
self.inner().weak_count()
434453
}
435454

src/tests.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,18 @@ fn test_weakref_without_cycles() {
116116
let w1 = s1.downgrade();
117117
let s2 = w1.upgrade().unwrap();
118118
let w2 = w1.clone();
119+
assert_eq!(s2.strong_count(), 2);
120+
assert_eq!(s2.weak_count(), 2);
121+
assert_eq!(w2.strong_count(), 2);
122+
assert_eq!(w2.weak_count(), 2);
119123
drop(s1);
120124
drop(s2);
121125
let w3 = w2.clone();
122126
assert!(w3.upgrade().is_none());
123127
assert!(w2.upgrade().is_none());
124128
assert!(w1.upgrade().is_none());
129+
assert_eq!(w3.strong_count(), 0);
130+
assert_eq!(w3.weak_count(), 3);
125131
});
126132
assert_eq!(
127133
log,
@@ -135,13 +141,21 @@ fn test_weakref_with_cycles() {
135141
let log = debug::capture_log(|| {
136142
debug::NEXT_DEBUG_NAME.with(|n| n.set(1));
137143
let a: Cc<RefCell<Vec<Box<dyn Trace>>>> = Cc::new(RefCell::new(Vec::new()));
144+
assert_eq!(a.strong_count(), 1);
138145
debug::NEXT_DEBUG_NAME.with(|n| n.set(2));
139146
let b: Cc<RefCell<Vec<Box<dyn Trace>>>> = Cc::new(RefCell::new(Vec::new()));
140147
a.borrow_mut().push(Box::new(b.clone()));
141148
b.borrow_mut().push(Box::new(a.clone()));
149+
assert_eq!(a.strong_count(), 2);
150+
assert_eq!(a.weak_count(), 0);
142151
let wa = a.downgrade();
152+
assert_eq!(a.weak_count(), 1);
143153
let wa1 = wa.clone();
154+
assert_eq!(a.weak_count(), 2);
144155
let wb = b.downgrade();
156+
assert_eq!(wa.strong_count(), 2);
157+
assert_eq!(wa.weak_count(), 2);
158+
assert_eq!(wb.weak_count(), 1);
145159
drop(a);
146160
drop(b);
147161
assert!(wa.upgrade().is_some());
@@ -151,6 +165,8 @@ fn test_weakref_with_cycles() {
151165
assert!(wa1.upgrade().is_none());
152166
assert!(wb.upgrade().is_none());
153167
assert!(wb.clone().upgrade().is_none());
168+
assert_eq!(wa.weak_count(), 2);
169+
assert_eq!(wa.strong_count(), 0);
154170
});
155171
assert_eq!(
156172
log,

0 commit comments

Comments
 (0)