rkyv/impls/alloc/rc/
atomic.rs

1use core::alloc::LayoutError;
2
3use ptr_meta::{from_raw_parts_mut, Pointee};
4use rancor::{Fallible, Source};
5
6use crate::{
7    alloc::{alloc::alloc, boxed::Box, sync},
8    de::{FromMetadata, Metadata, Pooling, PoolingExt as _, SharedPointer},
9    rc::{ArcFlavor, ArchivedRc, ArchivedRcWeak, RcResolver, RcWeakResolver},
10    ser::{Sharing, Writer},
11    traits::{ArchivePointee, LayoutRaw},
12    Archive, ArchiveUnsized, Deserialize, DeserializeUnsized, Place, Serialize,
13    SerializeUnsized,
14};
15
16// Arc
17
18impl<T: ArchiveUnsized + ?Sized> Archive for sync::Arc<T> {
19    type Archived = ArchivedRc<T::Archived, ArcFlavor>;
20    type Resolver = RcResolver;
21
22    fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
23        ArchivedRc::resolve_from_ref(self.as_ref(), resolver, out);
24    }
25}
26
27impl<T, S> Serialize<S> for sync::Arc<T>
28where
29    T: SerializeUnsized<S> + ?Sized + 'static,
30    S: Fallible + Writer + Sharing + ?Sized,
31    S::Error: Source,
32{
33    fn serialize(
34        &self,
35        serializer: &mut S,
36    ) -> Result<Self::Resolver, S::Error> {
37        ArchivedRc::<T::Archived, ArcFlavor>::serialize_from_ref(
38            self.as_ref(),
39            serializer,
40        )
41    }
42}
43
44unsafe impl<T: LayoutRaw + Pointee + ?Sized> SharedPointer<T> for sync::Arc<T> {
45    fn alloc(metadata: T::Metadata) -> Result<*mut T, LayoutError> {
46        let layout = T::layout_raw(metadata)?;
47        let data_address = if layout.size() > 0 {
48            unsafe { alloc(layout) }
49        } else {
50            crate::polyfill::dangling(&layout).as_ptr()
51        };
52        let ptr = from_raw_parts_mut(data_address.cast(), metadata);
53        Ok(ptr)
54    }
55
56    unsafe fn from_value(ptr: *mut T) -> *mut T {
57        let arc = sync::Arc::<T>::from(unsafe { Box::from_raw(ptr) });
58        sync::Arc::into_raw(arc).cast_mut()
59    }
60
61    unsafe fn drop(ptr: *mut T) {
62        drop(unsafe { sync::Arc::from_raw(ptr) });
63    }
64}
65
66impl<T, D> Deserialize<sync::Arc<T>, D> for ArchivedRc<T::Archived, ArcFlavor>
67where
68    T: ArchiveUnsized + LayoutRaw + Pointee + ?Sized + 'static,
69    T::Archived: DeserializeUnsized<T, D>,
70    T::Metadata: Into<Metadata> + FromMetadata,
71    D: Fallible + Pooling + ?Sized,
72    D::Error: Source,
73{
74    fn deserialize(
75        &self,
76        deserializer: &mut D,
77    ) -> Result<sync::Arc<T>, D::Error> {
78        let raw_shared_ptr =
79            deserializer.deserialize_shared::<_, sync::Arc<T>>(self.get())?;
80        unsafe {
81            sync::Arc::<T>::increment_strong_count(raw_shared_ptr);
82        }
83        unsafe { Ok(sync::Arc::<T>::from_raw(raw_shared_ptr)) }
84    }
85}
86
87impl<T, U> PartialEq<sync::Arc<U>> for ArchivedRc<T, ArcFlavor>
88where
89    T: ArchivePointee + PartialEq<U> + ?Sized,
90    U: ?Sized,
91{
92    fn eq(&self, other: &sync::Arc<U>) -> bool {
93        self.get().eq(other.as_ref())
94    }
95}
96
97// sync::Weak
98
99impl<T: ArchiveUnsized + ?Sized> Archive for sync::Weak<T> {
100    type Archived = ArchivedRcWeak<T::Archived, ArcFlavor>;
101    type Resolver = RcWeakResolver;
102
103    fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
104        ArchivedRcWeak::resolve_from_ref(
105            self.upgrade().as_ref().map(|v| v.as_ref()),
106            resolver,
107            out,
108        );
109    }
110}
111
112impl<T, S> Serialize<S> for sync::Weak<T>
113where
114    T: SerializeUnsized<S> + ?Sized + 'static,
115    S: Fallible + Writer + Sharing + ?Sized,
116    S::Error: Source,
117{
118    fn serialize(
119        &self,
120        serializer: &mut S,
121    ) -> Result<Self::Resolver, S::Error> {
122        ArchivedRcWeak::<T::Archived, ArcFlavor>::serialize_from_ref(
123            self.upgrade().as_ref().map(|v| v.as_ref()),
124            serializer,
125        )
126    }
127}
128
129// Deserialize can only be implemented for sized types because weak pointers
130// don't have from/into raw functions.
131impl<T, D> Deserialize<sync::Weak<T>, D>
132    for ArchivedRcWeak<T::Archived, ArcFlavor>
133where
134    // Deserialize can only be implemented for sized types because weak pointers
135    // to unsized types don't have `new` functions.
136    T: ArchiveUnsized
137        + LayoutRaw
138        + Pointee // + ?Sized
139        + 'static,
140    T::Archived: DeserializeUnsized<T, D>,
141    T::Metadata: Into<Metadata> + FromMetadata,
142    D: Fallible + Pooling + ?Sized,
143    D::Error: Source,
144{
145    fn deserialize(
146        &self,
147        deserializer: &mut D,
148    ) -> Result<sync::Weak<T>, D::Error> {
149        Ok(match self.upgrade() {
150            None => sync::Weak::new(),
151            Some(r) => sync::Arc::downgrade(&r.deserialize(deserializer)?),
152        })
153    }
154}