use std::fs::File;
use std::io::Result;
use std::ptr::NonNull;
use std::slice;
pub struct Arena {
ptr: NonNull<u8>,
len: usize,
}
impl Arena {
pub fn new(file: &File, len: usize, offset: usize) -> Result<Self> {
#[cfg(any(target_os = "linux", target_os = "android"))]
return {
let prot = libc::PROT_READ | libc::PROT_WRITE;
let flags = libc::MAP_SHARED;
let ptr = unsafe {
crate::ffi::linux_syscall::mmap(
std::ptr::null_mut(),
len,
prot,
flags,
file,
offset as _,
)
}?
.cast();
Ok(Self { ptr, len })
};
#[cfg(not(any(target_os = "linux", target_os = "android")))]
return {
let _ = file;
let _ = len;
let _ = offset;
Err(std::io::ErrorKind::Unsupported.into())
};
}
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
}
}
impl Drop for Arena {
fn drop(&mut self) {
#[cfg(any(target_os = "linux", target_os = "android"))]
if let Err(e) =
unsafe { crate::ffi::linux_syscall::munmap(self.ptr.as_ptr() as _, self.len) }
{
panic!("Failed to unmap arena: {}", e)
}
#[cfg(not(any(target_os = "linux", target_os = "android")))]
panic!("Failed to unmap arena: {}", std::io::ErrorKind::Unsupported);
}
}