}
}
+impl<P, T: ?Sized + ArenaAllocated<Payload = ManuallyDrop<P>>> TypedArenaPtr<T> {
+ pub fn drop_payload(&mut self) {
+ self.set_tag(ArenaHeaderTag::Dropped);
+ unsafe { ManuallyDrop::drop(&mut *self.as_ptr()) }
+ }
+}
+
impl<T: ?Sized + ArenaAllocated> TypedArenaPtr<T>
where
T::Payload: Sized,
}
}
+impl AllocateInArena<LiveLoadState> for LiveLoadState {
+ fn arena_allocate(self, arena: &mut Arena) -> TypedArenaPtr<LiveLoadState> {
+ LiveLoadState::alloc(arena, ManuallyDrop::new(self))
+ }
+}
+
impl ArenaAllocated for LiveLoadState {
- type Payload = Self;
+ type Payload = ManuallyDrop<Self>;
#[inline]
fn tag() -> ArenaHeaderTag {
ArenaHeaderTag::LiveLoadState
}
+
+ unsafe fn dealloc(ptr: NonNull<TypedAllocSlab<Self>>) {
+ let mut slab = unsafe { Box::from_raw(ptr.as_ptr()) };
+ unsafe { ManuallyDrop::drop(&mut slab.payload) };
+ drop(slab);
+ }
+}
+
+impl AllocateInArena<TcpListener> for TcpListener {
+ fn arena_allocate(self, arena: &mut Arena) -> TypedArenaPtr<TcpListener> {
+ TcpListener::alloc(arena, ManuallyDrop::new(self))
+ }
}
impl ArenaAllocated for TcpListener {
- type Payload = Self;
+ type Payload = ManuallyDrop<Self>;
#[inline]
fn tag() -> ArenaHeaderTag {
ArenaHeaderTag::TcpListener
}
impl<T: ?Sized + ArenaAllocated> TypedAllocSlab<T> {
+ pub fn payload(&mut self) -> &mut T::Payload {
+ &mut self.payload
+ }
+
/// # Safety
/// - ptr points to a valid allocation of Self
#[inline]
#[inline(always)]
fn evacuate(mut loader: Loader<'a, Self>) -> Result<Self::Evacuable, SessionError> {
if loader.payload.load_state.get_tag() != ArenaHeaderTag::Dropped {
- loader
- .payload
- .load_state
- .set_tag(ArenaHeaderTag::InactiveLoadState);
- Ok(loader.payload.load_state)
+ loader
+ .payload
+ .load_state
+ .set_tag(ArenaHeaderTag::InactiveLoadState);
+ Ok(loader.payload.load_state)
} else {
unreachable!("we never evacuate after dropping")
}
#[inline(always)]
fn reset_machine(loader: &mut Loader<'a, Self>) {
if loader.payload.load_state.get_tag() != ArenaHeaderTag::Dropped {
- loader.payload.load_state.set_tag(ArenaHeaderTag::Dropped);
+ loader.payload.load_state.drop_payload();
loader.reset_machine();
}
}
(HeapCellValueTag::Cons, cons_ptr) => {
match_untyped_arena_ptr!(cons_ptr,
(ArenaHeaderTag::LiveLoadState, payload) => {
- unsafe {
- std::ptr::drop_in_place(
- payload.as_ptr() as *mut LiveLoadState,
- );
- }
+ let mut payload = payload;
+ payload.drop_payload()
}
_ => {}
);
macro_rules! arena_allocated_impl_for_stream {
($stream_type:ty, $stream_tag:ident) => {
+ impl $crate::arena::AllocateInArena<$stream_tag> for StreamLayout<$stream_type> {
+ fn arena_allocate(self, arena: &mut Arena) -> TypedArenaPtr<$stream_tag> {
+ $stream_tag::alloc(arena, core::mem::ManuallyDrop::new(self))
+ }
+ }
+
impl ArenaAllocated for $stream_tag {
- type Payload = StreamLayout<$stream_type>;
+ type Payload = core::mem::ManuallyDrop<StreamLayout<$stream_type>>;
#[inline]
fn tag() -> ArenaHeaderTag {
ArenaHeaderTag::$stream_tag
}
+
+ unsafe fn dealloc(ptr: std::ptr::NonNull<TypedAllocSlab<Self>>) {
+ let mut slab = unsafe { Box::from_raw(ptr.as_ptr()) };
+ unsafe { std::mem::ManuallyDrop::drop(slab.payload()) };
+ drop(slab);
+ }
}
};
}
past_end_of_stream,
stream,
..
- } = &mut **stream_layout;
+ } = &mut ***stream_layout;
stream
.get_mut()
past_end_of_stream,
stream,
..
- } = &mut **stream_layout;
+ } = &mut ***stream_layout;
let cursor_len = stream.get_ref().0.get_ref().len() as u64;
cursor_position(past_end_of_stream, &stream.get_ref().0, cursor_len)
past_end_of_stream,
stream,
..
- } = &mut **stream_layout;
+ } = &mut ***stream_layout;
let cursor_len = stream.stream.get_ref().len() as u64;
cursor_position(past_end_of_stream, &stream.stream, cursor_len)
past_end_of_stream,
stream,
..
- } = &mut **stream_layout;
+ } = &mut ***stream_layout;
match stream.get_ref().file.metadata() {
Ok(metadata) => {
Stream::NamedTls(ref mut tls_stream) => tls_stream.inner_mut().tls_stream.shutdown(),
#[cfg(feature = "http")]
Stream::HttpRead(ref mut http_stream) => {
- unsafe {
- http_stream.set_tag(ArenaHeaderTag::Dropped);
- std::ptr::drop_in_place(&mut http_stream.inner_mut().body_reader as *mut _);
- }
+ http_stream.drop_payload();
Ok(())
}
#[cfg(feature = "http")]
- Stream::HttpWrite(ref mut http_stream) => {
- http_stream.inner_mut().drop();
- unsafe {
- http_stream.set_tag(ArenaHeaderTag::Dropped);
- std::ptr::drop_in_place(&mut http_stream.inner_mut().buffer as *mut _);
- }
+ Stream::HttpWrite(mut http_stream) => {
+ http_stream.drop_payload();
Ok(())
}
Stream::InputFile(mut file_stream) => {
// close the stream by dropping the inner File.
- unsafe {
- file_stream.set_tag(ArenaHeaderTag::Dropped);
- std::ptr::drop_in_place(&mut file_stream.inner_mut().file as *mut _);
- }
+ file_stream.drop_payload();
Ok(())
}
Stream::OutputFile(mut file_stream) => {
// close the stream by dropping the inner File.
- unsafe {
- file_stream.set_tag(ArenaHeaderTag::Dropped);
- std::ptr::drop_in_place(&mut file_stream.file as *mut _);
- }
+ file_stream.drop_payload();
Ok(())
}
(HeapCellValueTag::Cons, cons_ptr) => {
match_untyped_arena_ptr!(cons_ptr,
(ArenaHeaderTag::TcpListener, tcp_listener) => {
- unsafe {
- // dropping closes the instance.
- std::ptr::drop_in_place(&mut tcp_listener as *mut _);
- }
+ tcp_listener.drop_payload();
- tcp_listener.set_tag(ArenaHeaderTag::Dropped);
return Ok(());
}
_ => {