Skip to content

Commit a20076f

Browse files
authored
Implement I/O-safe traits (smol-rs#84)
1 parent 822511f commit a20076f

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ slab = "0.4.2"
2525
socket2 = { version = "0.4.2", features = ["all"] }
2626
waker-fn = "1.1.0"
2727

28+
[build-dependencies]
29+
autocfg = "1"
30+
2831
[target."cfg(unix)".dependencies]
2932
libc = "0.2.77"
3033

build.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fn main() {
2+
let cfg = match autocfg::AutoCfg::new() {
3+
Ok(cfg) => cfg,
4+
Err(e) => {
5+
println!(
6+
"cargo:warning=async-io: failed to detect compiler features: {}",
7+
e
8+
);
9+
return;
10+
}
11+
};
12+
13+
if !cfg.probe_rustc_version(1, 63) {
14+
autocfg::emit("async_io_no_io_safety");
15+
}
16+
}

src/lib.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ use std::sync::Arc;
6464
use std::task::{Context, Poll, Waker};
6565
use std::time::{Duration, Instant};
6666

67+
#[cfg(all(not(async_io_no_io_safety), unix))]
68+
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
6769
#[cfg(unix)]
6870
use std::{
6971
os::unix::io::{AsRawFd, RawFd},
@@ -73,6 +75,8 @@ use std::{
7375

7476
#[cfg(windows)]
7577
use std::os::windows::io::{AsRawSocket, RawSocket};
78+
#[cfg(all(not(async_io_no_io_safety), windows))]
79+
use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};
7680

7781
use futures_lite::io::{AsyncRead, AsyncWrite};
7882
use futures_lite::stream::{self, Stream};
@@ -552,6 +556,31 @@ impl<T: AsRawFd> AsRawFd for Async<T> {
552556
}
553557
}
554558

559+
#[cfg(all(not(async_io_no_io_safety), unix))]
560+
impl<T: AsFd> AsFd for Async<T> {
561+
fn as_fd(&self) -> BorrowedFd<'_> {
562+
self.get_ref().as_fd()
563+
}
564+
}
565+
566+
#[cfg(all(not(async_io_no_io_safety), unix))]
567+
impl<T: AsRawFd + From<OwnedFd>> TryFrom<OwnedFd> for Async<T> {
568+
type Error = io::Error;
569+
570+
fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
571+
Async::new(value.into())
572+
}
573+
}
574+
575+
#[cfg(all(not(async_io_no_io_safety), unix))]
576+
impl<T: Into<OwnedFd>> TryFrom<Async<T>> for OwnedFd {
577+
type Error = io::Error;
578+
579+
fn try_from(value: Async<T>) -> Result<Self, Self::Error> {
580+
value.into_inner().map(Into::into)
581+
}
582+
}
583+
555584
#[cfg(windows)]
556585
impl<T: AsRawSocket> Async<T> {
557586
/// Creates an async I/O handle.
@@ -612,6 +641,31 @@ impl<T: AsRawSocket> AsRawSocket for Async<T> {
612641
}
613642
}
614643

644+
#[cfg(all(not(async_io_no_io_safety), windows))]
645+
impl<T: AsSocket> AsSocket for Async<T> {
646+
fn as_socket(&self) -> BorrowedSocket<'_> {
647+
self.get_ref().as_socket()
648+
}
649+
}
650+
651+
#[cfg(all(not(async_io_no_io_safety), windows))]
652+
impl<T: AsRawSocket + From<OwnedSocket>> TryFrom<OwnedSocket> for Async<T> {
653+
type Error = io::Error;
654+
655+
fn try_from(value: OwnedSocket) -> Result<Self, Self::Error> {
656+
Async::new(value.into())
657+
}
658+
}
659+
660+
#[cfg(all(not(async_io_no_io_safety), windows))]
661+
impl<T: Into<OwnedSocket>> TryFrom<Async<T>> for OwnedSocket {
662+
type Error = io::Error;
663+
664+
fn try_from(value: Async<T>) -> Result<Self, Self::Error> {
665+
value.into_inner().map(Into::into)
666+
}
667+
}
668+
615669
impl<T> Async<T> {
616670
/// Gets a reference to the inner I/O handle.
617671
///

0 commit comments

Comments
 (0)