use std::convert::TryFrom;
use common::ShMemOps;
use error::Result;
use zerocopy::{AsBytes, FromBytes};
pub mod common;
pub mod error;
cfg_if::cfg_if! {
if #[cfg(unix)] {
mod unix;
use unix as sh;
} else if #[cfg(windows)] {
mod windows;
use windows as sh;
} else {
panic!("No shared memory model available for this platform.");
}
}
pub struct ShMemCfg<T>
where
T: AsBytes + FromBytes + Default,
{
owner: bool,
file_name: String,
init_value: Option<T>,
}
impl<T> Default for ShMemCfg<T>
where
T: AsBytes + FromBytes + Default,
{
fn default() -> Self {
let mut seed = [0_u8; 8];
getrandom::getrandom(&mut seed).expect("Error on getrandom!");
let mut rnd = oorandom::Rand32::new(u64::from_ne_bytes(seed));
cfg_if::cfg_if! {
if #[cfg(unix)] {
let name = format!("/shmem_{}", rnd.rand_u32());
} else if #[cfg(windows)] {
let name = format!("{}", rnd.rand_u32());
} else {
let name = String::new();
panic!();
}
};
Self {
owner: false,
file_name: name,
init_value: None,
}
}
}
impl<T> ShMemCfg<T>
where
T: AsBytes + FromBytes + Default,
{
pub fn on_file(mut self, name: &str) -> Self {
cfg_if::cfg_if! {
if #[cfg(unix)] {
let p_name = format!("/shmem_{}", name);
} else if #[cfg(windows)] {
let p_name = name.to_string();
} else {
let p_name = String::new();
panic!();
}
};
self.file_name = p_name;
self
}
pub fn set_owner(mut self) -> Self {
self.owner = true;
self
}
pub fn with_initial_value(mut self, init: T) -> Self {
self.init_value = Some(init);
self
}
pub fn build(self) -> Result<ShMem<T>> {
let map = sh::ShObj::try_from(self)?;
Ok(ShMem { map })
}
}
pub struct ShMem<T>
where
T: AsBytes + FromBytes + Default,
{
map: sh::ShObj<T>,
}
impl<T> ShMemOps<T> for ShMem<T>
where
T: AsBytes + FromBytes + Default,
{
unsafe fn get_t(&self) -> &T {
self.map.get_t()
}
unsafe fn get_t_mut(&mut self) -> &mut T {
self.map.get_t_mut()
}
}