2025-01-16 18:06:00 +02:00
|
|
|
use std::{
|
2025-02-18 11:27:54 +02:00
|
|
|
ffi::c_void,
|
2025-01-16 18:06:00 +02:00
|
|
|
io,
|
|
|
|
ops::{Deref, DerefMut},
|
2025-02-18 11:27:54 +02:00
|
|
|
os::fd::{AsRawFd, FromRawFd, OwnedFd, RawFd},
|
|
|
|
ptr::null_mut,
|
2025-01-16 18:06:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
use crate::sys;
|
|
|
|
|
2025-02-18 11:27:54 +02:00
|
|
|
pub struct SharedMemoryImpl {
|
|
|
|
fd: OwnedFd,
|
|
|
|
size: usize,
|
|
|
|
}
|
2025-01-16 18:06:00 +02:00
|
|
|
|
2025-02-18 11:27:54 +02:00
|
|
|
pub struct FileMappingImpl {
|
|
|
|
fd: OwnedFd,
|
|
|
|
pointer: *mut c_void,
|
|
|
|
size: usize,
|
|
|
|
}
|
2025-01-16 18:06:00 +02:00
|
|
|
|
|
|
|
impl sys::SharedMemory for SharedMemoryImpl {
|
|
|
|
type Mapping = FileMappingImpl;
|
|
|
|
|
|
|
|
fn map(self) -> io::Result<Self::Mapping> {
|
2025-02-18 11:27:54 +02:00
|
|
|
<FileMappingImpl as sys::FileMapping>::map(self.fd, self.size)
|
2025-01-16 18:06:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn new(size: usize) -> io::Result<Self> {
|
2025-02-18 11:27:54 +02:00
|
|
|
let fd = unsafe { libc::memfd_create(c"cross-shm".as_ptr(), libc::MFD_CLOEXEC) };
|
|
|
|
if fd < 0 {
|
|
|
|
return Err(io::Error::last_os_error());
|
|
|
|
}
|
|
|
|
let fd = unsafe { OwnedFd::from_raw_fd(fd) };
|
|
|
|
if unsafe { libc::ftruncate(fd.as_raw_fd(), size as i64) } != 0 {
|
|
|
|
return Err(io::Error::last_os_error());
|
|
|
|
}
|
|
|
|
Ok(Self { fd, size })
|
2025-01-16 18:06:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsRawFd for SharedMemoryImpl {
|
|
|
|
fn as_raw_fd(&self) -> RawFd {
|
2025-02-18 11:27:54 +02:00
|
|
|
self.fd.as_raw_fd()
|
2025-01-16 18:06:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl sys::FileMapping for FileMappingImpl {
|
|
|
|
fn map<F: Into<OwnedFd>>(file: F, size: usize) -> io::Result<Self> {
|
2025-02-18 11:27:54 +02:00
|
|
|
let fd: OwnedFd = file.into();
|
|
|
|
let pointer = unsafe {
|
|
|
|
libc::mmap(
|
|
|
|
null_mut(),
|
|
|
|
size,
|
|
|
|
libc::PROT_READ | libc::PROT_WRITE,
|
|
|
|
libc::MAP_SHARED,
|
|
|
|
fd.as_raw_fd(),
|
|
|
|
0,
|
|
|
|
)
|
|
|
|
};
|
|
|
|
if pointer == libc::MAP_FAILED {
|
|
|
|
return Err(io::Error::last_os_error());
|
|
|
|
}
|
|
|
|
Ok(Self { fd, pointer, size })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for FileMappingImpl {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
libc::munmap(self.pointer, self.size);
|
|
|
|
}
|
2025-01-16 18:06:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Deref for FileMappingImpl {
|
|
|
|
type Target = [u8];
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
2025-02-18 11:27:54 +02:00
|
|
|
unsafe { core::slice::from_raw_parts(self.pointer.cast(), self.size) }
|
2025-01-16 18:06:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DerefMut for FileMappingImpl {
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
2025-02-18 11:27:54 +02:00
|
|
|
unsafe { core::slice::from_raw_parts_mut(self.pointer.cast(), self.size) }
|
2025-01-16 18:06:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsRawFd for FileMappingImpl {
|
|
|
|
fn as_raw_fd(&self) -> RawFd {
|
2025-02-18 11:27:54 +02:00
|
|
|
self.fd.as_raw_fd()
|
2025-01-16 18:06:00 +02:00
|
|
|
}
|
|
|
|
}
|