diff --git a/Cargo.toml b/Cargo.toml index 0496986..1eda3bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,9 @@ slab = "0.4.2" socket2 = { version = "0.4.2", features = ["all"] } waker-fn = "1.1.0" +[build-dependencies] +autocfg = "1" + [target."cfg(unix)".dependencies] libc = "0.2.77" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..8292525 --- /dev/null +++ b/build.rs @@ -0,0 +1,16 @@ +fn main() { + let cfg = match autocfg::AutoCfg::new() { + Ok(cfg) => cfg, + Err(e) => { + println!( + "cargo:warning=async-io: failed to detect compiler features: {}", + e + ); + return; + } + }; + + if !cfg.probe_rustc_version(1, 63) { + autocfg::emit("async_io_no_io_safety"); + } +} diff --git a/src/lib.rs b/src/lib.rs index 29c3f5e..de6d526 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,6 +64,8 @@ use std::sync::Arc; use std::task::{Context, Poll, Waker}; use std::time::{Duration, Instant}; +#[cfg(all(not(async_io_no_io_safety), unix))] +use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; #[cfg(unix)] use std::{ os::unix::io::{AsRawFd, RawFd}, @@ -73,6 +75,8 @@ use std::{ #[cfg(windows)] use std::os::windows::io::{AsRawSocket, RawSocket}; +#[cfg(all(not(async_io_no_io_safety), windows))] +use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket}; use futures_lite::io::{AsyncRead, AsyncWrite}; use futures_lite::stream::{self, Stream}; @@ -552,6 +556,31 @@ impl AsRawFd for Async { } } +#[cfg(all(not(async_io_no_io_safety), unix))] +impl AsFd for Async { + fn as_fd(&self) -> BorrowedFd<'_> { + self.get_ref().as_fd() + } +} + +#[cfg(all(not(async_io_no_io_safety), unix))] +impl> TryFrom for Async { + type Error = io::Error; + + fn try_from(value: OwnedFd) -> Result { + Async::new(value.into()) + } +} + +#[cfg(all(not(async_io_no_io_safety), unix))] +impl> TryFrom> for OwnedFd { + type Error = io::Error; + + fn try_from(value: Async) -> Result { + value.into_inner().map(Into::into) + } +} + #[cfg(windows)] impl Async { /// Creates an async I/O handle. @@ -612,6 +641,31 @@ impl AsRawSocket for Async { } } +#[cfg(all(not(async_io_no_io_safety), windows))] +impl AsSocket for Async { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.get_ref().as_socket() + } +} + +#[cfg(all(not(async_io_no_io_safety), windows))] +impl> TryFrom for Async { + type Error = io::Error; + + fn try_from(value: OwnedSocket) -> Result { + Async::new(value.into()) + } +} + +#[cfg(all(not(async_io_no_io_safety), windows))] +impl> TryFrom> for OwnedSocket { + type Error = io::Error; + + fn try_from(value: Async) -> Result { + value.into_inner().map(Into::into) + } +} + impl Async { /// Gets a reference to the inner I/O handle. ///