#![cfg(any(target_os="android", target_os="l4re", target_os="linux", windows))]
#![doc(cfg(any(target_os="android", target_os="l4re", target_os="linux", windows)))]
use {
core::{
fmt::Display,
time::Duration,
},
std::{
io::{self, Error, ErrorKind, Write},
time::Instant,
},
crate::{Namaste, Result},
};
pub use self::rw_namaste::*;
macro_rules! sleep { () => {{
#[cfg(not(feature="tokio"))]
std::thread::sleep(SLEEP_DURATION);
#[cfg(feature="tokio")]
tokio::time::sleep(SLEEP_DURATION).await;
}}}
mod rw_namaste;
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, None);
}
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="tokio"))]
#[doc(cfg(not(feature="tokio")))]
pub fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
make_wait!(id, timeout)
}
#[cfg(feature="tokio")]
#[doc(cfg(feature="tokio"))]
pub async fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
make_wait!(id, timeout)
}
pub (crate) fn print_err<S>(msg: S) where S: Display {
let msg = format!("{}\n", msg.to_string().trim());
if io::stderr().lock().write_all(msg.as_bytes()).is_err() {
eprintln!("{}", msg.trim());
}
}