diff --git a/src/ext.rs b/src/ext.rs index 93b9832..1dc6229 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -5,6 +5,10 @@ use std::{ borrow::{ Borrow, BorrowMut }, + mem::{ + ManuallyDrop, + MaybeUninit, + }, }; /// Defer an expression call @@ -33,16 +37,22 @@ macro_rules! defer { pub(crate) use defer; /// Defer calling `F` until the destructor is ran -pub struct Deferred ()>(F); +#[repr(transparent)] +pub struct Deferred ()>(ManuallyDrop); /// Defer dropping this value until the container is dropped. The function `F` will be called on the value at drop time. -pub struct DeferredDrop ()>(T,F); +pub struct DeferredDrop ()>(T, ManuallyDrop); -impl ()> ops::Drop for Deferred +impl ())> ops::Drop for Deferred { #[inline] fn drop(&mut self) { - self.0(); + todo!("How tf do we get a Box from ManuallyDrop??? We might just have to `transmute()` its `assume_init_mut()` to a higher lifetime"); + /*let func_ptr = unsafe { + ptr::read(MaybeUninit::assume_init_mut(&mut self.0) as *mut F; + // aosidaosij oijoi jaoile FUCK THIS SHIT, I JUST WANNA CALL THE DAMN THINGt p: *mut F = ManuallyDrop::borrow_mut(&mut self.0) as *mut _; + }; + func_ptr();*/ } } @@ -50,7 +60,8 @@ impl ()> ops::Drop for DeferredDrop { #[inline] fn drop(&mut self) { - self.1(self.0); + todo!("See above...") + //self.1(self.0); } } diff --git a/src/lib.rs b/src/lib.rs index 48c6a7e..64d57b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ use ffi::c_try; pub mod hugetlb; -#[cfg(feature="file")] +//#[cfg(feature="file")] pub mod file; pub mod ring; //TODO @@ -135,6 +135,7 @@ impl MappedFile { { Self::try_new_buffer_raw::(file, len, None, false, flags) } + //TODO: XXX: Test this when we have implemented memfd. #[inline] pub(crate) fn try_new_buffer_raw>(file: T, len: usize, rings: impl Into>, allow_unsafe_writes: bool, flags: impl flags::MapFlags) -> Result<(MappedFile, MappedFile), TryNewError> { @@ -228,11 +229,11 @@ impl MappedFile { let mut root = try_map!(NULL, full_len, libc::PROT_NONE, libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, -1, 0); let pivots = { let rawfd = file.as_raw_fd(); - let pivots: io::Result> = std::iter::successors(unsafe { Some(root.0.as_mut_ptr().add(full_len)) }, |&x| unsafe { Some(x.sub(len * 2)) }) // Map in reverse, from end of `root`, and overwrite the `root` mapping last. + let pivots: io::Result> = std::iter::successors(unsafe { Some(root.0.as_mut_ptr().add(full_len - (len * 2))) }, |&x| unsafe { Some(x.sub(len * 2)) }) // Map in reverse, from end of `root`, and overwrite the `root` mapping last. .take(pages.get()) .map(|base| { - let tm = try_map_or!(base as *mut _, len, prot_w, flags | libc::MAP_FIXED, rawfd, 0)?; let rm = try_map_or!(base.add(len) as *mut _, len, prot_r, flags | libc::MAP_FIXED,rawfd, 0 )?; + let tm = try_map_or!(base as *mut _, len, prot_w, flags | libc::MAP_FIXED, rawfd, 0)?; Ok((tm, rm)) }) diff --git a/src/ring/buffer.rs b/src/ring/buffer.rs index 4cb53f5..08ac60f 100644 --- a/src/ring/buffer.rs +++ b/src/ring/buffer.rs @@ -171,3 +171,47 @@ impl Private &self.0 } } + +//TODO: use `dup()` to turn (MappedFile, MappedFile) -> (MappedFile, MappedFile) + +pub trait BufferExt +{ + fn detach(txrx: Self) -> (MappedFile, MappedFile); +} + +impl BufferExt for (MappedFile, MappedFile) +where B: TwoBufferProvider + AsRawFd, +T: FromRawFd, +{ + /// Detach a mapped dual buffer 2-tuple into regular mapped inner types. + #[inline] + fn detach((itx, irx): Self) -> (MappedFile, MappedFile) { + #[cold] + #[inline(never)] + fn _panic_bad_dup(fd: RawFd) -> ! + { + panic!("Failed to dup({fd}): {}", io::Error::last_os_error()) + } + let tx = itx.file.as_raw_fd(); + let rx = irx.file.as_raw_fd(); + + let (f0, f1) = unsafe { + let fd1 = libc::dup(tx); + if fd1 < 0 { + _panic_bad_dup(tx); + } + let fd2 = libc::dup(rx); + if fd2 < 0 { + _panic_bad_dup(rx); + } + (T::from_raw_fd(fd1), T::from_raw_fd(fd2)) + }; + (MappedFile { + map: itx.map, + file: f0, + }, MappedFile { + map: irx.map, + file: f1 + }) + } +}