#![allow(unsafe_code)]
#[cfg(not(any(
all(
any(target_os = "linux", target_os = "macos"),
any(target_arch = "x86_64", target_arch = "aarch64")
),
all(windows, any(target_arch = "x86_64", target_arch = "aarch64")),
)))]
compile_error!(
"net-io 0.3 declares its OS surface for x86_64 and aarch64 on Linux, macOS, and Windows; \
FreeBSD and the std-only fallback for other targets arrive in 0.5"
);
#[cfg(unix)]
mod unix;
#[cfg(unix)]
pub(crate) use unix::*;
#[cfg(windows)]
mod windows;
#[cfg(windows)]
pub(crate) use windows::*;
mod kill;
pub(crate) use kill::KillSlot;
#[cfg(any(test, net_io_shim))]
pub(crate) mod shim;
use std::io;
use std::time::Duration;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum Interest {
Read,
Write,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum Ready {
Socket,
Woken,
TimedOut,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum AcceptFailure {
PerConnection,
#[cfg_attr(windows, allow(dead_code))]
Descriptors,
Pressure,
ListenerFailed,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum AddrFailure {
InUse,
NotAvailable,
Permission,
Refused,
HostUnreachable,
NetworkUnreachable,
TimedOut,
Other,
}
pub(crate) fn poll_millis(timeout: Option<Duration>) -> i32 {
match timeout {
None => -1,
Some(d) => {
let ms = d
.as_millis()
.saturating_add(u128::from(d.subsec_nanos() % 1_000_000 != 0));
i32::try_from(ms).unwrap_or(i32::MAX)
}
}
}
pub(crate) fn retry_interrupted<T>(mut op: impl FnMut() -> io::Result<T>) -> io::Result<T> {
loop {
match op() {
Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
other => return other,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_poll_millis_rounds_up_and_caps() {
assert_eq!(poll_millis(None), -1);
assert_eq!(poll_millis(Some(Duration::from_millis(5))), 5);
assert_eq!(poll_millis(Some(Duration::from_micros(1))), 1);
assert_eq!(poll_millis(Some(Duration::from_secs(u64::MAX))), i32::MAX);
assert_eq!(poll_millis(Some(Duration::ZERO)), 0);
}
#[test]
fn test_retry_interrupted_retries_then_returns() {
let mut n = 0;
let r = retry_interrupted(|| {
n += 1;
if n < 3 {
Err(io::Error::from(io::ErrorKind::Interrupted))
} else {
Ok(n)
}
});
assert_eq!(r.unwrap(), 3);
}
}