Skip to content

Commit

Permalink
Add I/O-safe traits (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
notgull authored Aug 17, 2022
1 parent 0cde169 commit f54163f
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ exclude = ["/.*"]
async-io = "1.6.0"
blocking = "1.0.0"
futures-lite = "1.11.0"

[build-dependencies]
autocfg = "1"
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-net: failed to detect compiler features: {}",
e
);
return;
}
};

if !cfg.probe_rustc_version(1, 63) {
autocfg::emit("async_net_no_io_safety");
}
}
68 changes: 68 additions & 0 deletions src/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ use std::convert::TryFrom;
use std::fmt;
use std::io::{self, IoSlice, Read as _, Write as _};
use std::net::{Shutdown, SocketAddr};
#[cfg(all(not(async_net_no_io_safety), unix))]
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, RawSocket};
#[cfg(all(not(async_net_no_io_safety), windows))]
use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::pin::Pin;
use std::sync::Arc;
Expand Down Expand Up @@ -240,13 +244,45 @@ impl AsRawFd for TcpListener {
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl AsFd for TcpListener {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.get_ref().as_fd()
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl TryFrom<OwnedFd> for TcpListener {
type Error = io::Error;

fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
Self::try_from(std::net::TcpListener::from(value))
}
}

#[cfg(windows)]
impl AsRawSocket for TcpListener {
fn as_raw_socket(&self) -> RawSocket {
self.inner.as_raw_socket()
}
}

#[cfg(all(not(async_net_no_io_safety), windows))]
impl AsSocket for TcpListener {
fn as_socket(&self) -> BorrowedSocket<'_> {
self.inner.get_ref().as_socket()
}
}

#[cfg(all(not(async_net_no_io_safety), windows))]
impl TryFrom<OwnedSocket> for TcpListener {
type Error = io::Error;

fn try_from(value: OwnedSocket) -> Result<Self, Self::Error> {
Self::try_from(std::net::TcpListener::from(value))
}
}

/// A stream of incoming TCP connections.
///
/// This stream is infinite, i.e awaiting the next connection will never result in [`None`]. It is
Expand Down Expand Up @@ -574,13 +610,45 @@ impl AsRawFd for TcpStream {
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl AsFd for TcpStream {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.get_ref().as_fd()
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl TryFrom<OwnedFd> for TcpStream {
type Error = io::Error;

fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
Self::try_from(std::net::TcpStream::from(value))
}
}

#[cfg(windows)]
impl AsRawSocket for TcpStream {
fn as_raw_socket(&self) -> RawSocket {
self.inner.as_raw_socket()
}
}

#[cfg(all(not(async_net_no_io_safety), windows))]
impl AsSocket for TcpStream {
fn as_socket(&self) -> BorrowedSocket<'_> {
self.inner.get_ref().as_socket()
}
}

#[cfg(all(not(async_net_no_io_safety), windows))]
impl TryFrom<OwnedSocket> for TcpStream {
type Error = io::Error;

fn try_from(value: OwnedSocket) -> Result<Self, Self::Error> {
Self::try_from(std::net::TcpStream::from(value))
}
}

impl AsyncRead for TcpStream {
fn poll_read(
mut self: Pin<&mut Self>,
Expand Down
36 changes: 36 additions & 0 deletions src/udp.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use std::convert::TryFrom;
use std::io;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
#[cfg(all(not(async_net_no_io_safety), unix))]
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, RawSocket};
#[cfg(all(not(async_net_no_io_safety), windows))]
use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};
use std::sync::Arc;

use async_io::Async;
Expand Down Expand Up @@ -623,9 +627,41 @@ impl AsRawFd for UdpSocket {
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl AsFd for UdpSocket {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.get_ref().as_fd()
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl TryFrom<OwnedFd> for UdpSocket {
type Error = io::Error;

fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
Self::try_from(std::net::UdpSocket::from(value))
}
}

#[cfg(windows)]
impl AsRawSocket for UdpSocket {
fn as_raw_socket(&self) -> RawSocket {
self.inner.as_raw_socket()
}
}

#[cfg(all(not(async_net_no_io_safety), windows))]
impl AsSocket for UdpSocket {
fn as_socket(&self) -> BorrowedSocket<'_> {
self.inner.get_ref().as_socket()
}
}

#[cfg(all(not(async_net_no_io_safety), windows))]
impl TryFrom<OwnedSocket> for UdpSocket {
type Error = io::Error;

fn try_from(value: OwnedSocket) -> Result<Self, Self::Error> {
Self::try_from(std::net::UdpSocket::from(value))
}
}
34 changes: 34 additions & 0 deletions src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use std::convert::TryFrom;
use std::fmt;
use std::io::{self, Read as _, Write as _};
use std::net::Shutdown;
#[cfg(not(async_net_no_io_safety))]
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, RawFd};
#[cfg(windows)]
Expand Down Expand Up @@ -172,6 +174,22 @@ impl AsRawFd for UnixListener {
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl AsFd for UnixListener {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.get_ref().as_fd()
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl TryFrom<OwnedFd> for UnixListener {
type Error = io::Error;

fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
Self::try_from(std::os::unix::net::UnixListener::from(value))
}
}

#[cfg(windows)]
impl AsRawSocket for UnixListener {
fn as_raw_socket(&self) -> RawSocket {
Expand Down Expand Up @@ -371,6 +389,22 @@ impl AsRawFd for UnixStream {
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl AsFd for UnixStream {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.get_ref().as_fd()
}
}

#[cfg(all(not(async_net_no_io_safety), unix))]
impl TryFrom<OwnedFd> for UnixStream {
type Error = io::Error;

fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
Self::try_from(std::os::unix::net::UnixStream::from(value))
}
}

#[cfg(windows)]
impl AsRawSocket for UnixStream {
fn as_raw_socket(&self) -> RawSocket {
Expand Down

0 comments on commit f54163f

Please sign in to comment.