From 35cdd195130be61fae88c6ba952364038c313903 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Wed, 31 Jan 2024 23:54:22 +0100 Subject: [PATCH] write root target backref only once --- src/lib.rs | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 94d7a35..46b9828 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ use core::marker::PhantomPinned; use core::mem::{self, MaybeUninit}; use core::ops::{Deref, DerefMut}; use core::pin::Pin; -use core::ptr::NonNull; +use core::ptr::{self, NonNull}; pub trait Reclaim: Sized { fn reclaim(self, unclaimed: Unclaimed<Self>); @@ -80,7 +80,15 @@ impl<T> Root<T> { panic!("unclaimed called multiple times"); } self.state.set(STATE_UNCLAIMED); + let ptr = unsafe { NonNull::from(self.get_unchecked_mut()) }; + let ptr_erased = ptr.cast::<Root<Erased>>(); + + unsafe { + let target_root = ptr::addr_of_mut!((*(*ptr.as_ptr()).target.as_mut_ptr()).root); + target_root.write(Cell::new(Some(ptr_erased))); + } + Unclaimed { ptr } } } @@ -126,20 +134,18 @@ pub struct Unclaimed<T> { impl<T> Unclaimed<T> { pub fn claim(self, value: T) -> Xrc<T> { - let root_erased = self.ptr.cast::<Root<Erased>>(); - let target = unsafe { - (*self.ptr.as_ptr()).target.write(ProjectTarget { - root: Cell::new(Some(root_erased)), - value, - }) - }; - unsafe { (*self.ptr.as_ptr()).state.set(STATE_SHARED_INIT); } - // shared reborrow - let ptr = NonNull::from(&*target); + unsafe { + let target_value = ptr::addr_of_mut!((*(*self.ptr.as_ptr()).target.as_mut_ptr()).value); + target_value.write(value); + } + + // shared read-only reborrow + let target = unsafe { (*self.ptr.as_ptr()).target.assume_init_ref() }; + let ptr = NonNull::from(target); Xrc { ptr } } } -- GitLab