1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
/*
==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--
Namaste
Copyright (C) 2019, 2021-2024 Anonymous
There are several releases over multiple years,
they are listed as ranges, such as: "2021-2024".
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
*/
//! # Root
#![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="async-std"))]
std::thread::sleep(SLEEP_DURATION);
#[cfg(feature="async-std")]
async_std::task::sleep(SLEEP_DURATION).await;
}}}
mod rw_namaste;
/// # Sleep duration
pub (crate) const SLEEP_DURATION: Duration = Duration::from_millis(sleep_duration!());
/// # Makes new `Namaste`
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),
},
};
}
}}}
/// # Tries to make a `Namaste`...
///
/// If *the same ID is in use*, waits and tries again until timed out.
#[cfg(not(feature="async-std"))]
#[doc(cfg(not(feature="async-std")))]
pub fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
make_wait!(id, timeout)
}
/// # Tries to make a `Namaste`...
///
/// If *the same ID is in use*, waits and tries again until timed out.
#[cfg(feature="async-std")]
#[doc(cfg(feature="async-std"))]
pub async fn make_wait<B>(id: B, timeout: Duration) -> Result<Namaste> where B: AsRef<[u8]> {
make_wait!(id, timeout)
}
/// # Prints error
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());
}
}