use std::io::{self, Error as IoError, ErrorKind as IoErrorKind};
use std::ops::{Deref, DerefMut};
use std::ptr;
use crate::rdma::mr::*;
use crate::rdma::pd::*;
pub struct RegisteredMem {
mr: Mr,
buf: Box<[u8]>,
}
impl RegisteredMem {
pub fn new(pd: &Pd, len: usize) -> io::Result<Self> {
if len == 0 {
return Err(IoError::new(
IoErrorKind::InvalidInput,
"zero-length memory regions are disallowed",
));
}
let buf = vec![0u8; len].into_boxed_slice();
Self::new_owned(pd, buf).map_err(|(_, e)| e)
}
pub fn new_owned(pd: &Pd, buf: Box<[u8]>) -> Result<Self, (Box<[u8]>, IoError)> {
if buf.is_empty() {
return Err((
buf,
IoError::new(
IoErrorKind::InvalidInput,
"zero-length memory regions are disallowed",
),
));
}
let buf = Box::leak(buf);
let mr = unsafe { Mr::reg(pd, buf.as_mut_ptr(), buf.len(), Permission::default()) };
let buf = unsafe { Box::from_raw(buf) };
match mr {
Ok(mr) => Ok(Self { mr, buf }),
Err(e) => Err((buf, e)),
}
}
pub fn new_with_content(pd: &Pd, content: &[u8]) -> io::Result<Self> {
if content.is_empty() {
return Err(IoError::new(
IoErrorKind::InvalidInput,
"zero-length memory regions are disallowed",
));
}
let mut ret = Self::new(pd, content.len())?;
ret.buf.copy_from_slice(content);
Ok(ret)
}
#[inline]
pub fn addr(&self) -> *mut u8 {
self.buf.as_ptr() as *mut u8
}
#[inline]
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.buf.len()
}
#[inline]
pub fn mr(&self) -> &Mr {
&self.mr
}
#[inline]
pub fn clear(&mut self) {
unsafe {
ptr::write_bytes(self.buf.as_mut_ptr(), 0, self.buf.len());
}
}
}
impl Deref for RegisteredMem {
type Target = [u8];
#[inline]
fn deref(&self) -> &Self::Target {
self.buf.as_ref()
}
}
impl DerefMut for RegisteredMem {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.buf.as_mut()
}
}
unsafe impl<'s> Slicing<'s> for RegisteredMem {
type Output = MrSlice<'s>;
fn addr(&'s self) -> *mut u8 {
self.mr.addr()
}
fn len(&'s self) -> usize {
self.mr.len()
}
unsafe fn slice_unchecked(&'s self, offset: usize, len: usize) -> Self::Output {
MrSlice::new(&self.mr, offset, len)
}
}