Skip to main content

arc_gc/
arc.rs

1use std::{
2    collections::VecDeque,
3    sync::{atomic::AtomicUsize, Arc, Weak},
4};
5
6use crate::traceable::GCTraceable;
7
8/// GCWrapper 包装器,包含被垃圾回收的对象和附加的GC计数
9pub struct GCWrapper<T: GCTraceable<T> + 'static> {
10    value: T,
11    pub(crate) attached_gc_count: AtomicUsize,
12}
13
14impl<T: GCTraceable<T> + 'static> GCWrapper<T> {
15    pub fn new(value: T) -> Self {
16        Self {
17            value,
18            attached_gc_count: AtomicUsize::new(0),
19        }
20    }
21
22    pub fn value(&self) -> &T {
23        &self.value
24    }
25
26    pub fn value_mut(&mut self) -> &mut T {
27        &mut self.value
28    }
29}
30
31#[allow(dead_code)]
32pub trait GCRef {
33    fn strong_ref(&self) -> usize;
34    fn weak_ref(&self) -> usize;
35}
36
37pub struct GCArc<T: GCTraceable<T> + 'static> {
38    inner: Arc<GCWrapper<T>>,
39}
40
41impl<T: GCTraceable<T> + 'static> Into<GCArc<T>> for Arc<GCWrapper<T>> {
42    fn into(self) -> GCArc<T> {
43        GCArc { inner: self }
44    }
45}
46
47impl<T: GCTraceable<T> + 'static> From<GCArc<T>> for Arc<GCWrapper<T>> {
48    fn from(gc_arc: GCArc<T>) -> Self {
49        gc_arc.inner
50    }
51}
52
53#[allow(dead_code)]
54impl<T> GCArc<T>
55where
56    T: GCTraceable<T> + 'static,
57{
58    pub fn new(obj: T) -> Self {
59        Self {
60            inner: Arc::new(GCWrapper::new(obj)),
61        }
62    }
63    pub fn as_weak(&self) -> GCArcWeak<T> {
64        GCArcWeak {
65            inner: Arc::downgrade(&self.inner),
66        }
67    }
68
69    pub fn as_ref(&self) -> &T {
70        &self.inner.value
71    }
72
73    pub fn get_mut(&mut self) -> &mut T {
74        self.try_as_mut().expect(
75            "Cannot get mutable reference: GCArc is not unique. \
76             Strong count > 1 or weak references exist. \
77             Consider using interior mutability (RefCell, Mutex, etc.) instead.",
78        )
79    }
80
81    pub fn try_as_mut(&mut self) -> Option<&mut T> {
82        Arc::get_mut(&mut self.inner).map(|wrapper| &mut wrapper.value)
83    }
84
85    fn collect(&self, queue: &mut VecDeque<GCArcWeak<T>>) {
86        self.inner.value.collect(queue);
87    }
88
89    pub(crate) fn ptr_eq(a: &GCArc<T>, b: &GCArc<T>) -> bool {
90        Arc::ptr_eq(&a.inner, &b.inner)
91    }
92
93    #[inline(always)]
94    pub(crate) fn inner(&self) -> &GCWrapper<T> {
95        &self.inner
96    }
97}
98
99impl<T> Clone for GCArc<T>
100where
101    T: GCTraceable<T> + 'static,
102{
103    fn clone(&self) -> Self {
104        Self {
105            inner: self.inner.clone(),
106        }
107    }
108}
109
110impl<T> GCRef for GCArc<T>
111where
112    T: GCTraceable<T> + 'static,
113{
114    fn strong_ref(&self) -> usize {
115        Arc::strong_count(&self.inner)
116    }
117
118    fn weak_ref(&self) -> usize {
119        Arc::weak_count(&self.inner)
120    }
121}
122
123pub struct GCArcWeak<T: GCTraceable<T> + 'static> {
124    inner: Weak<GCWrapper<T>>,
125}
126
127impl<T: GCTraceable<T> + 'static> Into<GCArcWeak<T>> for Weak<GCWrapper<T>> {
128    fn into(self) -> GCArcWeak<T> {
129        GCArcWeak { inner: self }
130    }
131}
132
133impl<T: GCTraceable<T> + 'static> From<GCArcWeak<T>> for Weak<GCWrapper<T>> {
134    fn from(gc_arc_weak: GCArcWeak<T>) -> Self {
135        gc_arc_weak.inner
136    }
137}
138
139#[allow(dead_code)]
140impl<T> GCArcWeak<T>
141where
142    T: GCTraceable<T> + 'static,
143{
144    pub fn upgrade(&self) -> Option<GCArc<T>> {
145        self.inner.upgrade().map(|inner| GCArc { inner })
146    }
147
148    pub fn is_valid(&self) -> bool {
149        self.inner.strong_count() > 0
150    }
151}
152
153impl<T> Clone for GCArcWeak<T>
154where
155    T: GCTraceable<T> + 'static,
156{
157    fn clone(&self) -> Self {
158        Self {
159            inner: self.inner.clone(),
160        }
161    }
162}
163
164impl<T> GCRef for GCArcWeak<T>
165where
166    T: GCTraceable<T> + 'static,
167{
168    fn strong_ref(&self) -> usize {
169        self.inner.strong_count()
170    }
171
172    fn weak_ref(&self) -> usize {
173        self.inner.weak_count()
174    }
175}