use core::mem::transmute_copy;
use memmap2::{Mmap, MmapMut};
use std::{marker::PhantomData, sync::Arc};
pub struct MmapWrapper<T> {
raw: Arc<Mmap>,
_inner: PhantomData<T>,
}
impl<T> Clone for MmapWrapper<T> {
fn clone(&self) -> Self {
MmapWrapper {
raw: self.raw.clone(),
_inner: PhantomData,
}
}
}
pub struct MmapMutWrapper<T> {
raw: Arc<MmapMut>,
_inner: PhantomData<T>,
}
impl<T> Clone for MmapMutWrapper<T> {
fn clone(&self) -> Self {
MmapMutWrapper {
raw: self.raw.clone(),
_inner: PhantomData,
}
}
}
impl<T> From<Mmap> for MmapWrapper<T> {
fn from(m: Mmap) -> MmapWrapper<T> {
MmapWrapper::new(m)
}
}
impl<T> From<MmapMut> for MmapMutWrapper<T> {
fn from(m: MmapMut) -> MmapMutWrapper<T> {
unsafe { MmapMutWrapper::new(m) }
}
}
impl<T> MmapWrapper<T> {
pub fn new(m: Mmap) -> MmapWrapper<T> {
MmapWrapper {
raw: Arc::new(m),
_inner: PhantomData,
}
}
pub fn get_inner<'a>(&self) -> &'a T {
unsafe { &*self.raw.as_ptr().cast::<T>() }
}
}
impl<T> MmapMutWrapper<T> {
pub unsafe fn new(m: MmapMut) -> MmapMutWrapper<T> {
MmapMutWrapper {
raw: Arc::new(m),
_inner: PhantomData,
}
}
pub fn get_inner<'a>(&mut self) -> &'a mut T {
unsafe { &mut *self.raw.as_ptr().cast_mut().cast::<T>() }
}
}
#[cfg(test)]
mod tests {
struct TestStruct {
_thing1: i32,
}
use std::{
fs::{self, File},
thread,
};
use crate::MmapMutWrapper;
#[test]
fn arc_thread_test() {
let f = File::create_new("arc_thread_test").unwrap();
f.set_len(size_of::<TestStruct>().try_into().unwrap())
.unwrap();
let m = unsafe { memmap2::MmapMut::map_mut(&f).unwrap() };
let m: MmapMutWrapper<TestStruct> = unsafe { MmapMutWrapper::new(m) };
let m_clone = m.clone();
let t = thread::spawn(move || {
let _ = m_clone;
});
let _ = t.join();
drop(m);
fs::remove_file("arc_thread_test").unwrap();
}
}