shm: add a proper Drop implementation to MemMap
This commit is contained in:
parent
12dc3b65d8
commit
64a4fcb699
|
@ -49,17 +49,34 @@ struct MemMap {
|
||||||
impl MemMap {
|
impl MemMap {
|
||||||
fn new(fd: RawFd, size: usize) -> Result<MemMap,()> {
|
fn new(fd: RawFd, size: usize) -> Result<MemMap,()> {
|
||||||
Ok(MemMap {
|
Ok(MemMap {
|
||||||
ptr: map(fd, size)?,
|
ptr: unsafe { map(fd, size) }?,
|
||||||
fd: fd,
|
fd: fd,
|
||||||
size: size
|
size: size
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remap(&mut self, newsize: usize) -> Result<(),()> {
|
fn remap(&mut self, newsize: usize) -> Result<(),()> {
|
||||||
unmap(self.ptr, self.size)?;
|
if self.ptr.is_null() {
|
||||||
self.ptr = map(self.fd, newsize)?;
|
return Err(())
|
||||||
self.size = newsize;
|
}
|
||||||
Ok(())
|
// memunmap cannot fail, as we are unmapping a pre-existing map
|
||||||
|
let _ = unsafe { unmap(self.ptr, self.size) };
|
||||||
|
// remap the fd with the new size
|
||||||
|
match unsafe { map(self.fd, newsize) } {
|
||||||
|
Ok(ptr) => {
|
||||||
|
// update the parameters
|
||||||
|
self.ptr = ptr;
|
||||||
|
self.size = newsize;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
Err(()) => {
|
||||||
|
// set ourselves in an empty state
|
||||||
|
self.ptr = ptr::null_mut();
|
||||||
|
self.size = 0;
|
||||||
|
self.fd = -1;
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> usize {
|
fn size(&self) -> usize {
|
||||||
|
@ -67,27 +84,35 @@ impl MemMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_slice(&self) -> &[u8] {
|
fn get_slice(&self) -> &[u8] {
|
||||||
|
// if we are in the 'invalid state', self.size == 0 and we return &[]
|
||||||
|
// which is perfectly safe even if self.ptr is null
|
||||||
unsafe { ::std::slice::from_raw_parts(self.ptr, self.size) }
|
unsafe { ::std::slice::from_raw_parts(self.ptr, self.size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for MemMap {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !self.ptr.is_null() {
|
||||||
|
let _ = unsafe { unmap(self.ptr, self.size) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// mman::mmap should really be unsafe... why isn't it?
|
// mman::mmap should really be unsafe... why isn't it?
|
||||||
#[allow(unused_unsafe)]
|
unsafe fn map(fd: RawFd, size: usize) -> Result<*mut u8, ()> {
|
||||||
fn map(fd: RawFd, size: usize) -> Result<*mut u8, ()> {
|
let ret = mman::mmap(
|
||||||
let ret = unsafe { mman::mmap(
|
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
size,
|
size,
|
||||||
mman::PROT_READ,
|
mman::PROT_READ,
|
||||||
mman::MAP_SHARED,
|
mman::MAP_SHARED,
|
||||||
fd,
|
fd,
|
||||||
0
|
0
|
||||||
) };
|
);
|
||||||
ret.map(|p| p as *mut u8).map_err(|_| ())
|
ret.map(|p| p as *mut u8).map_err(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
// mman::munmap should really be unsafe... why isn't it?
|
// mman::munmap should really be unsafe... why isn't it?
|
||||||
#[allow(unused_unsafe)]
|
unsafe fn unmap(ptr: *mut u8, size: usize) -> Result<(),()> {
|
||||||
fn unmap(ptr: *mut u8, size: usize) -> Result<(),()> {
|
let ret = mman::munmap(ptr as *mut _, size);
|
||||||
let ret = unsafe { mman::munmap(ptr as *mut _, size) };
|
|
||||||
ret.map_err(|_| ())
|
ret.map_err(|_| ())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue