Skip to main content

rocketmq_rust/
arc_mut.rs

1// Copyright 2023 The RocketMQ Rust Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![allow(dead_code)]
16
17use core::fmt;
18use std::cell::SyncUnsafeCell;
19use std::fmt::Debug;
20use std::fmt::Formatter;
21use std::hash::Hash;
22use std::hash::Hasher;
23use std::ops::Deref;
24use std::ops::DerefMut;
25use std::sync::Arc;
26use std::sync::Weak;
27
28use serde::Deserialize;
29use serde::Deserializer;
30use serde::Serialize;
31use serde::Serializer;
32
33/// A weak version of `ArcMut` that doesn't prevent the inner value from being dropped.
34///
35/// # Safety
36/// This type uses `SyncUnsafeCell` which is not thread-safe by default.
37/// You must ensure that no data races occur when using this type across threads.
38pub struct WeakArcMut<T: ?Sized> {
39    inner: Weak<SyncUnsafeCell<T>>,
40}
41
42// Implementation of PartialEq for WeakArcMut<T>
43impl<T: PartialEq + ?Sized> PartialEq for WeakArcMut<T> {
44    fn eq(&self, other: &Self) -> bool {
45        if let (Some(a), Some(b)) = (self.inner.upgrade(), other.inner.upgrade()) {
46            unsafe { *a.get() == *b.get() }
47        } else {
48            false
49        }
50    }
51}
52
53// Implementation of Eq for WeakArcMut<T>
54impl<T: Eq + ?Sized> Eq for WeakArcMut<T> {}
55
56// Implementation of Hash for WeakArcMut<T>
57
58impl<T: Hash + ?Sized> Hash for WeakArcMut<T> {
59    fn hash<H: Hasher>(&self, state: &mut H) {
60        if let Some(arc) = self.inner.upgrade() {
61            unsafe { (*arc.get()).hash(state) }
62        }
63    }
64}
65
66impl<T: ?Sized> Clone for WeakArcMut<T> {
67    fn clone(&self) -> Self {
68        Self {
69            inner: self.inner.clone(),
70        }
71    }
72}
73
74impl<T: ?Sized> WeakArcMut<T> {
75    #[inline]
76    pub fn upgrade(&self) -> Option<ArcMut<T>> {
77        self.inner.upgrade().map(|inner| ArcMut { inner })
78    }
79}
80
81/// A mutable reference-counted pointer with interior mutability.
82///
83/// # Safety
84/// This type uses `SyncUnsafeCell` which is not thread-safe by default.
85/// You must ensure that no data races occur when using this type across threads.
86#[derive(Default)]
87pub struct ArcMut<T: ?Sized> {
88    inner: Arc<SyncUnsafeCell<T>>,
89}
90
91// Implementation of PartialEq for ArcMut<T>
92impl<T: PartialEq + ?Sized> PartialEq for ArcMut<T> {
93    fn eq(&self, other: &Self) -> bool {
94        unsafe { *self.inner.get() == *other.inner.get() }
95    }
96}
97
98impl<T: Eq + ?Sized> Eq for ArcMut<T> {}
99
100impl<T: Hash> Hash for ArcMut<T> {
101    #[inline]
102    fn hash<H: Hasher>(&self, state: &mut H) {
103        // Compute the hash of the inner value
104        unsafe { (*self.inner.get()).hash(state) }
105    }
106}
107
108impl<T> ArcMut<T> {
109    #[inline]
110    pub fn new(value: T) -> Self {
111        Self {
112            inner: Arc::new(SyncUnsafeCell::new(value)),
113        }
114    }
115
116    /// Returns a mutable reference to the inner value
117    ///
118    /// # Safety
119    /// This is safe as long as no other mutable references exist
120    /// and the caller ensures proper synchronization.
121    #[inline]
122    #[allow(clippy::mut_from_ref)]
123    pub fn mut_from_ref(&self) -> &mut T {
124        unsafe { &mut *self.inner.get() }
125    }
126
127    #[inline]
128    pub fn downgrade(this: &Self) -> WeakArcMut<T> {
129        WeakArcMut {
130            inner: Arc::downgrade(&this.inner),
131        }
132    }
133
134    #[inline]
135    pub fn get_inner(&self) -> &Arc<SyncUnsafeCell<T>> {
136        &self.inner
137    }
138
139    pub fn try_unwrap(self) -> Result<T, Self> {
140        match Arc::try_unwrap(self.inner) {
141            Ok(cell) => Ok(cell.into_inner()),
142            Err(inner) => Err(Self { inner }),
143        }
144    }
145
146    pub fn strong_count(&self) -> usize {
147        Arc::strong_count(&self.inner)
148    }
149
150    pub fn weak_count(&self) -> usize {
151        Arc::weak_count(&self.inner)
152    }
153}
154
155impl<T: ?Sized> Clone for ArcMut<T> {
156    #[inline]
157    fn clone(&self) -> Self {
158        ArcMut {
159            inner: Arc::clone(&self.inner),
160        }
161    }
162}
163
164impl<T: ?Sized> AsRef<T> for ArcMut<T> {
165    #[inline]
166    fn as_ref(&self) -> &T {
167        unsafe { &*self.inner.get() }
168    }
169}
170
171impl<T: ?Sized> AsMut<T> for ArcMut<T> {
172    #[inline]
173    fn as_mut(&mut self) -> &mut T {
174        unsafe { &mut *self.inner.get() }
175    }
176}
177
178impl<T: ?Sized> Deref for ArcMut<T> {
179    type Target = T;
180
181    #[inline]
182    fn deref(&self) -> &Self::Target {
183        self.as_ref()
184    }
185}
186
187impl<T: ?Sized> DerefMut for ArcMut<T> {
188    #[inline]
189    fn deref_mut(&mut self) -> &mut Self::Target {
190        self.as_mut()
191    }
192}
193
194pub struct SyncUnsafeCellWrapper<T: ?Sized> {
195    inner: SyncUnsafeCell<T>,
196}
197
198impl<T> SyncUnsafeCellWrapper<T> {
199    #[inline]
200    pub fn new(value: T) -> Self {
201        Self {
202            inner: SyncUnsafeCell::new(value),
203        }
204    }
205}
206
207impl<T> SyncUnsafeCellWrapper<T> {
208    #[inline]
209    #[allow(clippy::mut_from_ref)]
210    pub fn mut_from_ref(&self) -> &mut T {
211        unsafe { &mut *self.inner.get() }
212    }
213}
214
215impl<T> AsRef<T> for SyncUnsafeCellWrapper<T> {
216    #[inline]
217    fn as_ref(&self) -> &T {
218        unsafe { &*self.inner.get() }
219    }
220}
221
222impl<T> AsMut<T> for SyncUnsafeCellWrapper<T> {
223    #[inline]
224    fn as_mut(&mut self) -> &mut T {
225        &mut *self.inner.get_mut()
226    }
227}
228
229impl<T> Deref for SyncUnsafeCellWrapper<T> {
230    type Target = T;
231
232    #[inline]
233    fn deref(&self) -> &Self::Target {
234        self.as_ref()
235    }
236}
237
238impl<T> DerefMut for SyncUnsafeCellWrapper<T> {
239    #[inline]
240    fn deref_mut(&mut self) -> &mut Self::Target {
241        self.as_mut()
242    }
243}
244
245impl<T: ?Sized + Debug> std::fmt::Debug for ArcMut<T> {
246    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
247        fmt::Debug::fmt(&**self, f)
248    }
249}
250
251impl<T> Serialize for ArcMut<T>
252where
253    T: Serialize,
254{
255    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
256    where
257        S: Serializer,
258    {
259        let inner_ref = unsafe { &*self.inner.get() };
260        inner_ref.serialize(serializer)
261    }
262}
263
264impl<'de, T> Deserialize<'de> for ArcMut<T>
265where
266    T: Deserialize<'de>,
267{
268    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
269    where
270        D: Deserializer<'de>,
271    {
272        let inner = T::deserialize(deserializer)?;
273        Ok(ArcMut::new(inner))
274    }
275}
276
277#[cfg(test)]
278mod arc_cell_wrapper_tests {
279    use std::sync::Arc;
280
281    use super::*;
282
283    #[test]
284    fn new_creates_arc_cell_wrapper_with_provided_value() {
285        let wrapper = ArcMut::new(10);
286        assert_eq!(*wrapper.as_ref(), 10);
287    }
288
289    #[test]
290    fn clone_creates_a_new_instance_with_same_value() {
291        let wrapper = ArcMut::new(20);
292        let cloned_wrapper = wrapper.clone();
293        assert_eq!(*cloned_wrapper.as_ref(), 20);
294    }
295
296    #[test]
297    fn as_ref_returns_immutable_reference_to_value() {
298        let wrapper = ArcMut::new(30);
299        assert_eq!(*wrapper.as_ref(), 30);
300    }
301
302    #[test]
303    fn as_mut_returns_mutable_reference_to_value() {
304        let mut wrapper = ArcMut::new(40);
305        *wrapper.as_mut() = 50;
306        assert_eq!(*wrapper.as_ref(), 50);
307    }
308
309    #[test]
310    fn deref_returns_reference_to_inner_value() {
311        let wrapper = ArcMut::new(60);
312        assert_eq!(*wrapper, 60);
313    }
314
315    #[test]
316    fn deref_mut_allows_modification_of_inner_value() {
317        let mut wrapper = ArcMut::new(70);
318        *wrapper = 80;
319        assert_eq!(*wrapper, 80);
320    }
321
322    #[test]
323    fn multiple_clones_share_the_same_underlying_data() {
324        let wrapper = ArcMut::new(Arc::new(90));
325        let cloned_wrapper1 = wrapper.clone();
326        let cloned_wrapper2 = wrapper.clone();
327
328        assert_eq!(Arc::strong_count(wrapper.as_ref()), 1);
329        assert_eq!(Arc::strong_count(cloned_wrapper1.as_ref()), 1);
330        assert_eq!(Arc::strong_count(cloned_wrapper2.as_ref()), 1);
331    }
332}