#![cfg(any(target_os="linux", target_os="l4re", target_os="android", target_os="windows"))]
use {
core::time::Duration,
std::{
io::{Error, ErrorKind},
time::Instant,
},
crate::{Namaste, Result},
};
pub use self::rw_namaste::*;
macro_rules! sleep { () => {{
#[cfg(not(feature="async_std"))]
std::thread::sleep(SLEEP_DURATION);
#[cfg(feature="async_std")]
async_std::task::sleep(SLEEP_DURATION).await;
}}}
mod rw_namaste;
#[cfg(any(target_os="linux", target_os="l4re", target_os="android"))]
macro_rules! unclonable { () => { false }}
#[cfg(any(target_os="linux", target_os="l4re", target_os="android"))]
#[test]
fn tests() -> Result<()> {
assert!(unclonable!() == false);
Ok(())
}
pub (crate) const SLEEP_DURATION: Duration = Duration::from_millis(sleep_duration!());
pub fn make<B>(id: B) -> Result<Namaste> where B: AsRef<[u8]> {
let result;
#[cfg(windows)] {
result = Namaste::make(id, crate::windows::Instance::One);
}
#[cfg(any(target_os="linux", target_os="l4re", target_os="android"))] {
result = Namaste::make(id, unclonable!());
}
result
}
macro_rules! make_wait { ($id: ident, $timeout: ident) => {{
let start = Instant::now();
loop {
match make(&$id) {
Ok(namaste) => return Ok(namaste),
Err(err) => match err.kind() {
ErrorKind::AddrInUse => {
match Instant::now().checked_duration_since(start) {
Some(duration) => if duration > $timeout {
return Err(Error::new(ErrorKind::TimedOut, __!("Timed out")));
},
None => return Err(Error::new(ErrorKind::Other, __!("Invalid system time"))),
};
sleep!();
},
_ => return Err(err),
},
};
}
}}}
#[cfg(not(feature="async_std"))]
pub fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
make_wait!(id, timeout)
}
#[cfg(feature="async_std")]
pub async fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
make_wait!(id, timeout)
}