Skip to main content

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