Skip to content

Commit

Permalink
Implement I/O-safe traits (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
notgull authored Aug 17, 2022
1 parent 822511f commit a20076f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
16 changes: 16 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -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");
}
}
54 changes: 54 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -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};
Expand Down Expand Up @@ -552,6 +556,31 @@ impl<T: AsRawFd> AsRawFd for Async<T> {
}
}

#[cfg(all(not(async_io_no_io_safety), unix))]
impl<T: AsFd> AsFd for Async<T> {
fn as_fd(&self) -> BorrowedFd<'_> {
self.get_ref().as_fd()
}
}

#[cfg(all(not(async_io_no_io_safety), unix))]
impl<T: AsRawFd + From<OwnedFd>> TryFrom<OwnedFd> for Async<T> {
type Error = io::Error;

fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
Async::new(value.into())
}
}

#[cfg(all(not(async_io_no_io_safety), unix))]
impl<T: Into<OwnedFd>> TryFrom<Async<T>> for OwnedFd {
type Error = io::Error;

fn try_from(value: Async<T>) -> Result<Self, Self::Error> {
value.into_inner().map(Into::into)
}
}

#[cfg(windows)]
impl<T: AsRawSocket> Async<T> {
/// Creates an async I/O handle.
Expand Down Expand Up @@ -612,6 +641,31 @@ impl<T: AsRawSocket> AsRawSocket for Async<T> {
}
}

#[cfg(all(not(async_io_no_io_safety), windows))]
impl<T: AsSocket> AsSocket for Async<T> {
fn as_socket(&self) -> BorrowedSocket<'_> {
self.get_ref().as_socket()
}
}

#[cfg(all(not(async_io_no_io_safety), windows))]
impl<T: AsRawSocket + From<OwnedSocket>> TryFrom<OwnedSocket> for Async<T> {
type Error = io::Error;

fn try_from(value: OwnedSocket) -> Result<Self, Self::Error> {
Async::new(value.into())
}
}

#[cfg(all(not(async_io_no_io_safety), windows))]
impl<T: Into<OwnedSocket>> TryFrom<Async<T>> for OwnedSocket {
type Error = io::Error;

fn try_from(value: Async<T>) -> Result<Self, Self::Error> {
value.into_inner().map(Into::into)
}
}

impl<T> Async<T> {
/// Gets a reference to the inner I/O handle.
///
Expand Down

0 comments on commit a20076f

Please sign in to comment.