Enable RCU to support Weak

This commit is contained in:
Chen Chengjun 2025-04-10 10:41:33 +08:00 committed by Tate, Hongliang Tian
parent a21e895102
commit 6aba270a9b

View File

@ -3,6 +3,7 @@
//! This module provides a trait and some auxiliary types to help abstract and
//! work with non-null pointers.
use alloc::sync::Weak;
use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull};
use crate::prelude::*;
@ -188,3 +189,55 @@ unsafe impl<T: Send + Sync + 'static> NonNullPtr for Arc<T> {
NonNullPtr::into_raw(ManuallyDrop::into_inner(ptr_ref.inner))
}
}
/// A type that represents `&'a Weak<T>`.
#[derive(Debug)]
pub struct WeakRef<'a, T> {
inner: ManuallyDrop<Weak<T>>,
_marker: PhantomData<&'a Weak<T>>,
}
impl<T> Deref for WeakRef<'_, T> {
type Target = Weak<T>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
unsafe impl<T: Send + Sync + 'static> NonNullPtr for Weak<T> {
type Target = T;
type Ref<'a>
= WeakRef<'a, T>
where
Self: 'a;
fn into_raw(self) -> NonNull<Self::Target> {
let ptr = Weak::into_raw(self).cast_mut();
// SAFETY: The pointer representing an `Weak` can never be NULL.
unsafe { NonNull::new_unchecked(ptr) }
}
unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self {
let ptr = ptr.as_ptr().cast_const();
// SAFETY: The safety is upheld by the caller.
unsafe { Weak::from_raw(ptr) }
}
unsafe fn raw_as_ref<'a>(raw: NonNull<Self::Target>) -> Self::Ref<'a> {
// SAFETY: The safety is upheld by the caller.
unsafe {
WeakRef {
inner: ManuallyDrop::new(Weak::from_raw(raw.as_ptr())),
_marker: PhantomData,
}
}
}
fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> NonNull<Self::Target> {
NonNullPtr::into_raw(ManuallyDrop::into_inner(ptr_ref.inner))
}
}