1#![cfg(any(target_os="android", target_os="l4re", target_os="linux", windows))]
30#![doc(cfg(any(target_os="android", target_os="l4re", target_os="linux", windows)))]
31
32use {
33 core::{
34 fmt::Display,
35 time::Duration,
36 },
37 std::{
38 io::{self, Error, ErrorKind, Write},
39 time::Instant,
40 },
41 crate::{Namaste, Result},
42};
43
44pub use self::rw_namaste::*;
45
46macro_rules! sleep { () => {{
47 #[cfg(not(feature="tokio"))]
48 std::thread::sleep(SLEEP_DURATION);
49 #[cfg(feature="tokio")]
50 tokio::time::sleep(SLEEP_DURATION).await;
51}}}
52
53mod rw_namaste;
54
55pub (crate) const SLEEP_DURATION: Duration = Duration::from_millis(sleep_duration!());
57
58pub fn make<B>(id: B) -> Result<Namaste> where B: AsRef<[u8]> {
60 let result;
61
62 #[cfg(windows)] {
63 result = Namaste::make(id, crate::windows::Instance::One);
64 }
65
66 #[cfg(any(target_os="linux", target_os="l4re", target_os="android"))] {
67 result = Namaste::make(id, None);
68 }
69
70 result
71}
72
73macro_rules! make_wait { ($id: ident, $timeout: ident) => {{
74 let start = Instant::now();
75 loop {
76 match make(&$id) {
77 Ok(namaste) => return Ok(namaste),
78 Err(err) => match err.kind() {
79 ErrorKind::AddrInUse => {
80 match Instant::now().checked_duration_since(start) {
81 Some(duration) => if duration > $timeout {
82 return Err(Error::new(ErrorKind::TimedOut, __!("Timed out")));
83 },
84 None => return Err(Error::new(ErrorKind::Other, __!("Invalid system time"))),
85 };
86 sleep!();
87 },
88 _ => return Err(err),
89 },
90 };
91 }
92}}}
93
94#[cfg(not(feature="tokio"))]
98#[doc(cfg(not(feature="tokio")))]
99pub fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
100 make_wait!(id, timeout)
101}
102
103#[cfg(feature="tokio")]
107#[doc(cfg(feature="tokio"))]
108pub async fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
109 make_wait!(id, timeout)
110}
111
112pub (crate) fn print_err<S>(msg: S) where S: Display {
114 let msg = format!("{}\n", msg.to_string().trim());
115 if io::stderr().lock().write_all(msg.as_bytes()).is_err() {
116 eprintln!("{}", msg.trim());
117 }
118}