abi_stable/std_types/
arc.rs

1//! Contains the ffi-safe equivalent of `std::sync::Arc`.
2
3use std::{borrow::Borrow, marker::PhantomData, mem::ManuallyDrop, sync::Arc};
4
5use core_extensions::SelfOps;
6
7use crate::{
8    abi_stability::StableAbi,
9    marker_type::ErasedPrefix,
10    pointer_trait::{
11        AsPtr, CallReferentDrop, CanTransmuteElement, GetPointerKind, PK_SmartPointer,
12    },
13    prefix_type::{PrefixRef, WithMetadata},
14    std_types::{
15        utypeid::{new_utypeid, UTypeId},
16        RResult,
17    },
18};
19
20#[cfg(all(test, not(feature = "only_new_tests")))]
21mod test;
22
23mod private {
24    use super::*;
25
26    /// Ffi-safe version of `std::sync::Arc`
27    ///
28    /// # Example
29    ///
30    /// Using an `RArc<RMutex<RVec<u32>>>` to get a list populated from multiple threads.
31    ///
32    /// ```
33    /// use abi_stable::{
34    ///     external_types::RMutex,
35    ///     std_types::{RArc, RVec},
36    /// };
37    ///
38    /// use std::thread;
39    ///
40    /// let arc = RArc::new(RMutex::new(RVec::new()));
41    ///
42    /// {
43    ///     let arc2 = RArc::clone(&arc);
44    ///     assert!(std::ptr::eq(&*arc, &*arc2));
45    /// }
46    ///
47    /// let mut guards = Vec::new();
48    ///
49    /// for i in 0..10_u64 {
50    ///     let arc = RArc::clone(&arc);
51    ///     guards.push(thread::spawn(move || {
52    ///         for j in 0..100_u64 {
53    ///             arc.lock().push(i * 100 + j);
54    ///         }
55    ///     }));
56    /// }
57    ///
58    /// for guard in guards {
59    ///     guard.join().unwrap();
60    /// }
61    ///
62    /// let mut vec = RArc::try_unwrap(arc)
63    ///     .ok()
64    ///     .expect("All the threads were joined, so this must be the only RArc")
65    ///     .into_inner();
66    ///
67    /// vec.sort();
68    ///
69    /// assert_eq!(vec, (0..1000).collect::<RVec<_>>());
70    ///
71    /// ```
72    ///
73    #[derive(StableAbi)]
74    #[repr(C)]
75    pub struct RArc<T> {
76        data: *const T,
77        #[sabi(unsafe_change_type = ArcVtable_Ref<T>)]
78        vtable: PrefixRef<ErasedPrefix>,
79        _marker: PhantomData<T>,
80    }
81
82    impl_from_rust_repr! {
83        impl[T] From<Arc<T>> for RArc<T> {
84            fn(this){
85                RArc {
86                    data: Arc::into_raw(this),
87                    vtable: unsafe{ VTableGetter::<T>::LIB_VTABLE.0.cast() },
88                    _marker: Default::default(),
89                }
90            }
91        }
92    }
93
94    unsafe impl<T> GetPointerKind for RArc<T> {
95        type Kind = PK_SmartPointer;
96
97        type PtrTarget = T;
98    }
99
100    unsafe impl<T> AsPtr for RArc<T> {
101        fn as_ptr(&self) -> *const T {
102            self.data
103        }
104    }
105
106    unsafe impl<T, O> CanTransmuteElement<O> for RArc<T> {
107        type TransmutedPtr = RArc<O>;
108
109        unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
110            unsafe { core_extensions::utils::transmute_ignore_size(self) }
111        }
112    }
113
114    impl<T> RArc<T> {
115        #[inline(always)]
116        pub(super) const fn data(&self) -> *const T {
117            self.data
118        }
119
120        #[inline(always)]
121        pub(super) unsafe fn data_mut(&mut self) -> *mut T {
122            self.data as *mut T
123        }
124
125        #[inline]
126        pub(crate) fn into_raw(self) -> *const T {
127            let this = ManuallyDrop::new(self);
128            this.data
129        }
130
131        #[inline(always)]
132        pub(crate) const fn vtable(&self) -> ArcVtable_Ref<T> {
133            unsafe { ArcVtable_Ref::<T>(self.vtable.cast()) }
134        }
135
136        #[allow(dead_code)]
137        #[cfg(test)]
138        pub(super) fn set_vtable_for_testing(&mut self) {
139            self.vtable = unsafe { VTableGetter::<T>::LIB_VTABLE_FOR_TESTING.0.cast() };
140        }
141    }
142}
143
144pub use self::private::RArc;
145
146impl<T> RArc<T> {
147    /// Constructs an `RArc` from a value.
148    ///
149    /// # Example
150    ///
151    /// ```
152    /// use abi_stable::std_types::RArc;
153    ///
154    /// let arc = RArc::new(100);
155    ///
156    /// ```
157    pub fn new(this: T) -> Self {
158        Arc::new(this).into()
159    }
160
161    /// Converts this `RArc<T>` into an `Arc<T>`
162    ///
163    /// # Allocators
164    ///
165    /// `RArc<T>` cannot always be converted to an `Arc<T>`,
166    /// because their allocators *might* be different.
167    ///
168    /// # When is T cloned
169    ///
170    /// `T` is cloned if the current dynamic_library/executable is
171    /// not the one that created the `RArc<T>`,
172    /// and the strong count is greater than 1.
173    ///
174    /// # Example
175    ///
176    /// ```
177    /// use abi_stable::std_types::RArc;
178    /// use std::sync::Arc;
179    ///
180    /// let arc = RArc::new(100);
181    ///
182    /// assert_eq!(RArc::into_arc(arc), Arc::new(100));
183    ///
184    /// ```
185    pub fn into_arc(this: Self) -> Arc<T>
186    where
187        T: Clone,
188    {
189        let this_vtable = this.vtable();
190        let other_vtable = VTableGetter::LIB_VTABLE;
191        if ::std::ptr::eq(this_vtable.0.to_raw_ptr(), other_vtable.0.to_raw_ptr())
192            || this_vtable.type_id()() == other_vtable.type_id()()
193        {
194            unsafe { Arc::from_raw(this.into_raw()) }
195        } else {
196            Self::try_unwrap(this)
197                .unwrap_or_else(|x| T::clone(&x))
198                .piped(Arc::new)
199        }
200    }
201
202    /// Attempts to unwrap this `RArc<T>` into a `T`,
203    /// returns `Err(self)` if the `RArc<T>`'s strong count is greater than 1.
204    ///
205    /// # Example
206    ///
207    /// ```
208    /// use abi_stable::std_types::RArc;
209    ///
210    /// let arc0 = RArc::new(100);
211    /// assert_eq!(RArc::try_unwrap(arc0), Ok(100));
212    ///
213    /// let arc1 = RArc::new(100);
214    /// let arc1_clone = RArc::clone(&arc1);
215    /// assert_eq!(RArc::try_unwrap(arc1), Err(arc1_clone.clone()));
216    ///
217    /// ```
218    #[inline]
219    pub fn try_unwrap(this: Self) -> Result<T, Self> {
220        let vtable = this.vtable();
221        unsafe { (vtable.try_unwrap())(this).into_result() }
222    }
223
224    /// Attempts to create a mutable reference to `T`,
225    /// failing if the `RArc<T>`'s strong count is greater than 1.
226    ///
227    /// # Example
228    ///
229    /// ```
230    /// use abi_stable::std_types::RArc;
231    ///
232    /// let mut arc0 = RArc::new(100);
233    /// *RArc::get_mut(&mut arc0).unwrap() += 400;
234    /// assert_eq!(*arc0, 500);
235    ///
236    /// let mut arc1 = RArc::new(100);
237    /// let _arc1_clone = RArc::clone(&arc1);
238    /// assert_eq!(RArc::get_mut(&mut arc1), None);
239    ///
240    /// ```
241    #[inline]
242    pub fn get_mut(this: &mut Self) -> Option<&mut T> {
243        let vtable = this.vtable();
244        unsafe { (vtable.get_mut())(this) }
245    }
246
247    /// Makes a mutable reference to `T`.
248    ///
249    /// If there are other `RArc<T>`s pointing to the same value,
250    /// then `T` is cloned into a new `RArc<T>` to ensure unique ownership of the value.
251    ///
252    ///
253    /// # Postconditions
254    ///
255    /// After this call, the strong count of `this` will be 1,
256    /// because either it was 1 before the call,
257    /// or because a new `RArc<T>` was created to ensure unique ownership of `T`.
258    ///
259    /// # Example
260    ///
261    /// ```
262    /// use abi_stable::std_types::RArc;
263    ///
264    /// let mut arc0 = RArc::new(100);
265    /// *RArc::make_mut(&mut arc0) += 400;
266    /// assert_eq!(*arc0, 500);
267    ///
268    /// let mut arc1 = RArc::new(100);
269    /// let arc1_clone = RArc::clone(&arc1);
270    /// *RArc::make_mut(&mut arc1) += 400;
271    /// assert_eq!(*arc1, 500);
272    /// assert_eq!(*arc1_clone, 100);
273    ///
274    /// ```
275    #[inline]
276    pub fn make_mut(this: &mut Self) -> &mut T
277    where
278        T: Clone,
279    {
280        // Workaround for non-lexical lifetimes not being smart enough
281        // to figure out that this borrow doesn't continue in the None branch.
282        let unbounded_this = unsafe { &mut *(this as *mut Self) };
283        match Self::get_mut(unbounded_this) {
284            Some(x) => x,
285            None => {
286                let new_arc = RArc::new((**this).clone());
287                *this = new_arc;
288                // This is fine, since this is a freshly created arc with a clone of the data.
289                unsafe { &mut *this.data_mut() }
290            }
291        }
292    }
293
294    /// Gets the number of `RArc` that point to the value.
295    ///
296    /// # Example
297    ///
298    /// ```
299    /// use abi_stable::std_types::RArc;
300    ///
301    /// let arc = RArc::new(0);
302    /// assert_eq!(RArc::strong_count(&arc), 1);
303    ///
304    /// let clone = RArc::clone(&arc);
305    /// assert_eq!(RArc::strong_count(&arc), 2);
306    ///
307    /// ```
308    pub fn strong_count(this: &Self) -> usize {
309        let vtable = this.vtable();
310        unsafe { vtable.strong_count()(this) }
311    }
312
313    /// Gets the number of `std::sync::Weak` that point to the value.
314    ///
315    /// # Example
316    ///
317    /// ```
318    /// use abi_stable::std_types::RArc;
319    ///
320    /// use std::sync::Arc;
321    ///
322    /// let rustarc = Arc::new(0);
323    /// let arc = RArc::from(rustarc.clone());
324    /// assert_eq!(RArc::weak_count(&arc), 0);
325    ///
326    /// let weak_0 = Arc::downgrade(&rustarc);
327    /// assert_eq!(RArc::weak_count(&arc), 1);
328    ///
329    /// let weak_1 = Arc::downgrade(&rustarc);
330    /// assert_eq!(RArc::weak_count(&arc), 2);
331    /// ```
332    pub fn weak_count(this: &Self) -> usize {
333        let vtable = this.vtable();
334        unsafe { vtable.weak_count()(this) }
335    }
336}
337
338////////////////////////////////////////////////////////////////////
339
340impl<T> Borrow<T> for RArc<T> {
341    fn borrow(&self) -> &T {
342        self
343    }
344}
345
346impl<T> AsRef<T> for RArc<T> {
347    fn as_ref(&self) -> &T {
348        self
349    }
350}
351
352////////////////////////////////////////////////////////////////////
353
354impl<T> Default for RArc<T>
355where
356    T: Default,
357{
358    fn default() -> Self {
359        RArc::new(T::default())
360    }
361}
362
363impl<T> Clone for RArc<T> {
364    fn clone(&self) -> Self {
365        unsafe { (self.vtable().clone_())(self) }
366    }
367}
368
369impl_into_rust_repr! {
370    impl[T] Into<Arc<T>> for RArc<T>
371    where[
372        T: Clone+StableAbi,
373    ]{
374        fn(this){
375            RArc::into_arc(this)
376        }
377    }
378}
379
380impl<T> Drop for RArc<T> {
381    fn drop(&mut self) {
382        // The layout of the RArc<_> won't change since it doesn't
383        // actually support ?Sized types.
384        unsafe {
385            let vtable = self.vtable();
386            (vtable.destructor())(self.data() as *const T, CallReferentDrop::Yes);
387        }
388    }
389}
390
391shared_impls! {pointer
392    mod = arc_impls
393    new_type = RArc[][T],
394    original_type = Arc,
395}
396
397unsafe impl<T> Sync for RArc<T> where T: Send + Sync {}
398
399unsafe impl<T> Send for RArc<T> where T: Send + Sync {}
400
401impl<T> Unpin for RArc<T> {}
402
403/////////////////////////////////////////////////////////
404
405mod vtable_mod {
406    use super::*;
407
408    pub(super) struct VTableGetter<'a, T>(&'a T);
409
410    impl<'a, T: 'a> VTableGetter<'a, T> {
411        const DEFAULT_VTABLE: ArcVtable<T> = ArcVtable {
412            type_id: new_utypeid::<RArc<()>>,
413            destructor: destructor_arc::<T>,
414            clone_: clone_arc::<T>,
415            get_mut: get_mut_arc::<T>,
416            try_unwrap: try_unwrap_arc::<T>,
417            strong_count: strong_count_arc::<T>,
418            weak_count: weak_count_arc::<T>,
419        };
420
421        staticref! {
422            const WM_DEFAULT: WithMetadata<ArcVtable<T>> =
423                WithMetadata::new(Self::DEFAULT_VTABLE)
424        }
425
426        // The VTABLE for this type in this executable/library
427        pub(super) const LIB_VTABLE: ArcVtable_Ref<T> =
428            { ArcVtable_Ref(Self::WM_DEFAULT.as_prefix()) };
429
430        #[cfg(test)]
431        staticref! {const WM_FOR_TESTING: WithMetadata<ArcVtable<T>> =
432            WithMetadata::new(
433                ArcVtable{
434                    type_id: new_utypeid::<RArc<i32>>,
435                    ..Self::DEFAULT_VTABLE
436                }
437            )
438        }
439
440        #[cfg(test)]
441        pub(super) const LIB_VTABLE_FOR_TESTING: ArcVtable_Ref<T> =
442            { ArcVtable_Ref(Self::WM_FOR_TESTING.as_prefix()) };
443    }
444
445    #[derive(StableAbi)]
446    #[repr(C)]
447    #[sabi(kind(Prefix))]
448    #[sabi(missing_field(panic))]
449    pub struct ArcVtable<T> {
450        pub(super) type_id: extern "C" fn() -> UTypeId,
451        pub(super) destructor: unsafe extern "C" fn(*const T, CallReferentDrop),
452        pub(super) clone_: unsafe extern "C" fn(&RArc<T>) -> RArc<T>,
453        pub(super) get_mut: unsafe extern "C" fn(&mut RArc<T>) -> Option<&mut T>,
454        pub(super) try_unwrap: unsafe extern "C" fn(RArc<T>) -> RResult<T, RArc<T>>,
455        pub(super) strong_count: unsafe extern "C" fn(&RArc<T>) -> usize,
456        #[sabi(last_prefix_field)]
457        pub(super) weak_count: unsafe extern "C" fn(&RArc<T>) -> usize,
458    }
459
460    unsafe extern "C" fn destructor_arc<T>(this: *const T, call_drop: CallReferentDrop) {
461        extern_fn_panic_handling! {no_early_return; unsafe {
462            if call_drop == CallReferentDrop::Yes {
463                drop(Arc::from_raw(this));
464            } else {
465                drop(Arc::from_raw(this as *const ManuallyDrop<T>));
466            }
467        }}
468    }
469
470    unsafe fn with_arc_ref<T, F, R>(this: &RArc<T>, f: F) -> R
471    where
472        F: FnOnce(&Arc<T>) -> R,
473    {
474        let x = this.data();
475        let x = unsafe { Arc::from_raw(x) };
476        let x = ManuallyDrop::new(x);
477        f(&x)
478    }
479
480    unsafe extern "C" fn clone_arc<T>(this: &RArc<T>) -> RArc<T> {
481        unsafe { with_arc_ref(this, |x| Arc::clone(x).into()) }
482    }
483
484    unsafe extern "C" fn get_mut_arc<'a, T>(this: &'a mut RArc<T>) -> Option<&'a mut T> {
485        let arc = unsafe { Arc::from_raw(this.data()) };
486        let mut arc = ManuallyDrop::new(arc);
487        // This is fine, since we are only touching the data afterwards,
488        // which is guaranteed to have the 'a lifetime.
489        let arc: &'a mut Arc<T> = unsafe { &mut *(&mut *arc as *mut Arc<T>) };
490        Arc::get_mut(arc)
491    }
492
493    unsafe extern "C" fn try_unwrap_arc<T>(this: RArc<T>) -> RResult<T, RArc<T>> {
494        this.into_raw()
495            .piped(|x| unsafe { Arc::from_raw(x) })
496            .piped(Arc::try_unwrap)
497            .map_err(RArc::from)
498            .into()
499    }
500
501    unsafe extern "C" fn strong_count_arc<T>(this: &RArc<T>) -> usize {
502        unsafe { with_arc_ref(this, |x| Arc::strong_count(x)) }
503    }
504
505    unsafe extern "C" fn weak_count_arc<T>(this: &RArc<T>) -> usize {
506        unsafe { with_arc_ref(this, |x| Arc::weak_count(x)) }
507    }
508}
509use self::vtable_mod::{ArcVtable_Ref, VTableGetter};