MappedFile: Added `try_new_buffer()`.

Fortune for mapped-file's current commit: Half blessing − 半吉
master
Avril 2 years ago
parent ec26e0e9ed
commit e96c2274c3
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -5,6 +5,10 @@ use std::{
borrow::{ borrow::{
Borrow, BorrowMut Borrow, BorrowMut
}, },
mem::{
ManuallyDrop,
MaybeUninit,
},
}; };
/// Defer an expression call /// Defer an expression call
@ -33,16 +37,22 @@ macro_rules! defer {
pub(crate) use defer; pub(crate) use defer;
/// Defer calling `F` until the destructor is ran /// Defer calling `F` until the destructor is ran
pub struct Deferred<F: ?Sized + FnOnce() -> ()>(F); #[repr(transparent)]
pub struct Deferred<F: ?Sized + FnOnce() -> ()>(ManuallyDrop<F>);
/// Defer dropping this value until the container is dropped. The function `F` will be called on the value at drop time. /// 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: ?Sized + FnOnce(T) -> ()>(T,F); pub struct DeferredDrop<T, F: ?Sized + FnOnce(T) -> ()>(T, ManuallyDrop<F>);
impl<F: ?Sized+ FnOnce() -> ()> ops::Drop for Deferred<F> impl<F: ?Sized+ (FnOnce() -> ())> ops::Drop for Deferred<F>
{ {
#[inline] #[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.0(); todo!("How tf do we get a Box<F> from ManuallyDrop<F>??? 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<T, F: ?Sized+ FnOnce(T) -> ()> ops::Drop for DeferredDrop<T, F>
{ {
#[inline] #[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.1(self.0); todo!("See above...")
//self.1(self.0);
} }
} }

@ -27,7 +27,7 @@ use ffi::c_try;
pub mod hugetlb; pub mod hugetlb;
#[cfg(feature="file")] //#[cfg(feature="file")]
pub mod file; pub mod file;
pub mod ring; //TODO pub mod ring; //TODO
@ -135,6 +135,7 @@ impl<T: AsRawFd> MappedFile<T> {
{ {
Self::try_new_buffer_raw::<B>(file, len, None, false, flags) Self::try_new_buffer_raw::<B>(file, len, None, false, flags)
} }
//TODO: XXX: Test this when we have implemented memfd.
#[inline] #[inline]
pub(crate) fn try_new_buffer_raw<B: buffer::TwoBufferProvider<T>>(file: T, len: usize, rings: impl Into<Option<std::num::NonZeroUsize>>, allow_unsafe_writes: bool, flags: impl flags::MapFlags) -> Result<(MappedFile<B>, MappedFile<B>), TryNewError<T>> pub(crate) fn try_new_buffer_raw<B: buffer::TwoBufferProvider<T>>(file: T, len: usize, rings: impl Into<Option<std::num::NonZeroUsize>>, allow_unsafe_writes: bool, flags: impl flags::MapFlags) -> Result<(MappedFile<B>, MappedFile<B>), TryNewError<T>>
{ {
@ -228,11 +229,11 @@ impl<T: AsRawFd> MappedFile<T> {
let mut root = try_map!(NULL, full_len, libc::PROT_NONE, libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, -1, 0); let mut root = try_map!(NULL, full_len, libc::PROT_NONE, libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, -1, 0);
let pivots = { let pivots = {
let rawfd = file.as_raw_fd(); let rawfd = file.as_raw_fd();
let pivots: io::Result<Vec<_>> = 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<Vec<_>> = 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()) .take(pages.get())
.map(|base| { .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 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)) Ok((tm, rm))
}) })

@ -171,3 +171,47 @@ impl<T: ?Sized> Private<T>
&self.0 &self.0
} }
} }
//TODO: use `dup()` to turn (MappedFile<B>, MappedFile<B>) -> (MappedFile<impl FromRawFd>, MappedFile<impl FromRawFd>)
pub trait BufferExt<T>
{
fn detach(txrx: Self) -> (MappedFile<T>, MappedFile<T>);
}
impl<B, T> BufferExt<T> for (MappedFile<B>, MappedFile<B>)
where B: TwoBufferProvider<T> + AsRawFd,
T: FromRawFd,
{
/// Detach a mapped dual buffer 2-tuple into regular mapped inner types.
#[inline]
fn detach((itx, irx): Self) -> (MappedFile<T>, MappedFile<T>) {
#[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
})
}
}

Loading…
Cancel
Save