From 3f6078945cb5c8986089d92d9f19c0dacdddd834 Mon Sep 17 00:00:00 2001 From: Johannes Hostert Date: Mon, 26 Aug 2024 16:19:54 +0200 Subject: [PATCH] fix approach 2: use unsafecell --- core/arena/unique_arena.rs | 28 +++++++------------------ core/runtime/op_driver/erased_future.rs | 9 +++++--- core/runtime/op_driver/future_arena.rs | 14 +++++++------ 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/core/arena/unique_arena.rs b/core/arena/unique_arena.rs index 8d8e16ca5..a07a0d939 100644 --- a/core/arena/unique_arena.rs +++ b/core/arena/unique_arena.rs @@ -59,8 +59,8 @@ impl ArenaBox { /// This function returns a raw pointer without managing the memory, potentially leading to /// memory leaks if the pointer is not properly handled or deallocated. #[inline(always)] - pub fn into_raw(mut alloc: ArenaBox) -> NonNull { - let ptr = NonNull::from(alloc.data_mut()); + pub fn into_raw(alloc: ArenaBox) -> NonNull { + let ptr: NonNull> = alloc.ptr; std::mem::forget(alloc); unsafe { Self::ptr_from_data(ptr) } } @@ -91,8 +91,10 @@ impl ArenaBox { } #[inline(always)] - fn data_mut(&mut self) -> &mut ArenaBoxData { - unsafe { self.ptr.as_mut() } + pub(crate) fn deref_data(&self) -> NonNull { + unsafe { + NonNull::new_unchecked(std::ptr::addr_of_mut!((*self.ptr.as_ptr()).data)) + } } } @@ -120,20 +122,6 @@ impl std::convert::AsRef for ArenaBox { } } -impl std::ops::DerefMut for ArenaBox { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.data_mut().data - } -} - -impl std::convert::AsMut for ArenaBox { - #[inline(always)] - fn as_mut(&mut self) -> &mut T { - &mut self.data_mut().data - } -} - impl std::future::Future for ArenaBox where F: Future, @@ -142,10 +130,10 @@ where #[inline(always)] fn poll( - mut self: Pin<&mut Self>, + self: Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll { - unsafe { F::poll(Pin::new_unchecked(&mut self.data_mut().data), cx) } + unsafe { F::poll(Pin::new_unchecked(self.deref_data().as_mut()), cx) } } } diff --git a/core/runtime/op_driver/erased_future.rs b/core/runtime/op_driver/erased_future.rs index 2399992b9..08bc6e2fd 100644 --- a/core/runtime/op_driver/erased_future.rs +++ b/core/runtime/op_driver/erased_future.rs @@ -38,8 +38,11 @@ impl TypeErased { } #[inline(always)] - pub fn raw_ptr(&mut self) -> NonNull { - unsafe { NonNull::new_unchecked(self.memory.as_mut_ptr() as *mut _) } + /// Safety: This uses a place projection to `this.memory`, which must be in-bounds. + pub unsafe fn raw_ptr(this: *mut Self) -> NonNull { + unsafe { + NonNull::new_unchecked(std::ptr::addr_of_mut!((*this).memory) as *mut _) + } } #[inline(always)] @@ -70,7 +73,7 @@ impl TypeErased { impl Drop for TypeErased { fn drop(&mut self) { - (self.drop)(self.raw_ptr::<()>()) + (self.drop)(unsafe { Self::raw_ptr(self) }) } } diff --git a/core/runtime/op_driver/future_arena.rs b/core/runtime/op_driver/future_arena.rs index 26c170102..339dff36e 100644 --- a/core/runtime/op_driver/future_arena.rs +++ b/core/runtime/op_driver/future_arena.rs @@ -3,6 +3,7 @@ use super::erased_future::TypeErased; use crate::arena::ArenaBox; use crate::arena::ArenaUnique; use pin_project::pin_project; +use std::cell::UnsafeCell; use std::future::Future; use std::marker::PhantomData; use std::mem::MaybeUninit; @@ -25,7 +26,7 @@ pub trait FutureContextMapper { struct DynFutureInfoErased { ptr: MaybeUninit>>, - data: TypeErased, + data: UnsafeCell>, } pub trait ContextFuture: Future { @@ -190,19 +191,20 @@ impl FutureArena { { unsafe { if let Some(reservation) = self.arena.reserve_space() { - let mut alloc = self.arena.complete_reservation( + let alloc = self.arena.complete_reservation( reservation, DynFutureInfoErased { ptr: MaybeUninit::uninit(), - data: TypeErased::new(DynFutureInfo { + data: UnsafeCell::new(TypeErased::new(DynFutureInfo { context, future, _phantom: PhantomData, - }), + })), }, ); - let ptr = alloc.data.raw_ptr::>(); - alloc.ptr.write(ptr); + let ptr = + TypeErased::raw_ptr::>(alloc.data.get()); + (*alloc.deref_data().as_ptr()).ptr.write(ptr); return TypedFutureAllocation { inner: FutureAllocation::Arena(alloc), ptr,