Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement new I/O-safe traits on types #1606

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ jobs:
override: true
- name: Check
# We only run check allowing us to use newer features in tests.
run: cargo check --all-features
# notgull: exclude the io_safety feature since that requires 1.63
run: cargo check --features "os-ext,net"
Nightly:
runs-on: ubuntu-latest
timeout-minutes: 10
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ os-ext = [
]
# Enables `mio::net` module containing networking primitives.
net = []
# Implement I/O-safe traits on `mio` objects, like `AsFd`
# Requires Rust 1.63.0
io_safety = []

[dependencies]
log = "0.4.8"
Expand Down
11 changes: 11 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@ pub mod features {
#![cfg_attr(not(feature = "net"), doc = "## Network types (disabled)")]
//!
//! The `net` feature enables networking primitives in the `net` module.
//!
#![cfg_attr(feature = "io_safety", doc = "## I/O Safety (enabled)")]
#![cfg_attr(not(feature = "io_safety"), doc = "## I/O Safety (disabled)")]
//!
//! The `io_safety` feature adds the [`AsFd`] and [`AsSocket`] traits to
//! Mio types. These traits allow you to use Mio types using these I/O safe
//! traits. In addition, `From<OwnedFd> for ...` and `From<...> for OwnedFd`
//! is implemented for Mio types.
//!
//! [`AsFd`]: std::os::unix::io::AsFd
//! [`AsSocket`]: std::os::windows::io::AsSocket
}

pub mod guide {
Expand Down
69 changes: 69 additions & 0 deletions src/net/tcp/listener.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
use std::net::{self, SocketAddr};
#[cfg(all(feature = "io_safety", unix))]
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(all(feature = "io_safety", target_os = "wasi"))]
use std::os::wasi::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(target_os = "wasi")]
use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
#[cfg(all(feature = "io_safety", windows))]
use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};
use std::{fmt, io};

use crate::io_source::IoSource;
Expand Down Expand Up @@ -193,6 +199,27 @@ impl FromRawFd for TcpListener {
}
}

#[cfg(all(feature = "io_safety", unix))]
impl AsFd for TcpListener {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}

#[cfg(all(feature = "io_safety", unix))]
impl From<OwnedFd> for TcpListener {
fn from(fd: OwnedFd) -> Self {
TcpListener::from_std(fd.into())
}
}

#[cfg(all(feature = "io_safety", unix))]
impl From<TcpListener> for OwnedFd {
fn from(tl: TcpListener) -> Self {
tl.inner.into_inner().into()
}
}

#[cfg(windows)]
impl IntoRawSocket for TcpListener {
fn into_raw_socket(self) -> RawSocket {
Expand Down Expand Up @@ -220,6 +247,27 @@ impl FromRawSocket for TcpListener {
}
}

#[cfg(all(feature = "io_safety", windows))]
impl AsSocket for TcpListener {
fn as_socket(&self) -> BorrowedSocket<'_> {
self.inner.as_socket()
}
}

#[cfg(all(feature = "io_safety", windows))]
impl From<OwnedSocket> for TcpListener {
fn from(socket: OwnedSocket) -> Self {
TcpListener::from_std(socket.into())
}
}

#[cfg(all(feature = "io_safety", windows))]
impl From<TcpListener> for OwnedSocket {
fn from(tl: TcpListener) -> Self {
tl.inner.into_inner().into()
}
}

#[cfg(target_os = "wasi")]
impl IntoRawFd for TcpListener {
fn into_raw_fd(self) -> RawFd {
Expand All @@ -246,3 +294,24 @@ impl FromRawFd for TcpListener {
TcpListener::from_std(FromRawFd::from_raw_fd(fd))
}
}

#[cfg(all(feature = "io_safety", target_os = "wasi"))]
impl AsFd for TcpListener {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}

#[cfg(all(feature = "io_safety", target_os = "wasi"))]
impl From<OwnedFd> for TcpListener {
fn from(fd: OwnedFd) -> Self {
TcpListener::from_std(fd.into())
}
}

#[cfg(all(feature = "io_safety", target_os = "wasi"))]
impl From<TcpListener> for OwnedFd {
fn from(tl: TcpListener) -> Self {
tl.inner.into_inner().into()
}
}
69 changes: 69 additions & 0 deletions src/net/tcp/stream.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
use std::fmt;
use std::io::{self, IoSlice, IoSliceMut, Read, Write};
use std::net::{self, Shutdown, SocketAddr};
#[cfg(all(feature = "io_safety", unix))]
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(all(feature = "io_safety", target_os = "wasi"))]
use std::os::wasi::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(target_os = "wasi")]
use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
#[cfg(all(feature = "io_safety", windows))]
use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};

use crate::io_source::IoSource;
#[cfg(not(target_os = "wasi"))]
Expand Down Expand Up @@ -372,6 +378,27 @@ impl FromRawFd for TcpStream {
}
}

#[cfg(all(feature = "io_safety", unix))]
impl AsFd for TcpStream {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}

#[cfg(all(feature = "io_safety", unix))]
impl From<OwnedFd> for TcpStream {
fn from(fd: OwnedFd) -> TcpStream {
TcpStream::from_std(fd.into())
}
}

#[cfg(all(feature = "io_safety", unix))]
impl From<TcpStream> for OwnedFd {
fn from(ts: TcpStream) -> Self {
ts.inner.into_inner().into()
}
}

#[cfg(windows)]
impl IntoRawSocket for TcpStream {
fn into_raw_socket(self) -> RawSocket {
Expand Down Expand Up @@ -399,6 +426,27 @@ impl FromRawSocket for TcpStream {
}
}

#[cfg(all(feature = "io_safety", windows))]
impl AsSocket for TcpStream {
fn as_socket(&self) -> BorrowedSocket<'_> {
self.inner.as_socket()
}
}

#[cfg(all(feature = "io_safety", windows))]
impl From<OwnedSocket> for TcpStream {
fn from(fd: OwnedSocket) -> TcpStream {
TcpStream::from_std(fd.into())
}
}

#[cfg(all(feature = "io_safety", windows))]
impl From<TcpStream> for OwnedSocket {
fn from(ts: TcpStream) -> Self {
ts.inner.into_inner().into()
}
}

#[cfg(target_os = "wasi")]
impl IntoRawFd for TcpStream {
fn into_raw_fd(self) -> RawFd {
Expand All @@ -425,3 +473,24 @@ impl FromRawFd for TcpStream {
TcpStream::from_std(FromRawFd::from_raw_fd(fd))
}
}

#[cfg(all(feature = "io_safety", target_os = "wasi"))]
impl AsFd for TcpStream {
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_fd()
}
}

#[cfg(all(feature = "io_safety", target_os = "wasi"))]
impl From<OwnedFd> for TcpStream {
fn from(fd: OwnedFd) -> TcpStream {
TcpStream::from_std(fd.into())
}
}

#[cfg(all(feature = "io_safety", target_os = "wasi"))]
impl From<TcpStream> for OwnedFd {
fn from(ts: TcpStream) -> Self {
ts.inner.into_inner().into()
}
}
46 changes: 46 additions & 0 deletions src/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ use std::fmt;
use std::io;
use std::net;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
#[cfg(all(feature = "io_safety", unix))]
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
#[cfg(all(feature = "io_safety", windows))]
use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};

/// A User Datagram Protocol socket.
///
Expand Down Expand Up @@ -669,6 +673,27 @@ impl FromRawFd for UdpSocket {
}
}

#[cfg(all(feature = "io_safety", unix))]
impl AsFd for UdpSocket {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}

#[cfg(all(feature = "io_safety", unix))]
impl From<OwnedFd> for UdpSocket {
fn from(fd: OwnedFd) -> Self {
UdpSocket::from_std(fd.into())
}
}

#[cfg(all(feature = "io_safety", unix))]
impl From<UdpSocket> for OwnedFd {
fn from(s: UdpSocket) -> Self {
s.inner.into_inner().into()
}
}

#[cfg(windows)]
impl IntoRawSocket for UdpSocket {
fn into_raw_socket(self) -> RawSocket {
Expand All @@ -695,3 +720,24 @@ impl FromRawSocket for UdpSocket {
UdpSocket::from_std(FromRawSocket::from_raw_socket(socket))
}
}

#[cfg(all(feature = "io_safety", windows))]
impl AsSocket for UdpSocket {
fn as_socket(&self) -> BorrowedSocket<'_> {
self.inner.as_socket()
}
}

#[cfg(all(feature = "io_safety", windows))]
impl From<OwnedSocket> for UdpSocket {
fn from(socket: OwnedSocket) -> Self {
UdpSocket::from_std(socket.into())
}
}

#[cfg(all(feature = "io_safety", windows))]
impl From<UdpSocket> for OwnedSocket {
fn from(s: UdpSocket) -> Self {
s.inner.into_inner().into()
}
}
23 changes: 23 additions & 0 deletions src/net/uds/datagram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use crate::io_source::IoSource;
use crate::{event, sys, Interest, Registry, Token};

use std::net::Shutdown;
#[cfg(feature = "io_safety")]
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use std::os::unix::net;
use std::path::Path;
Expand Down Expand Up @@ -234,3 +236,24 @@ impl FromRawFd for UnixDatagram {
UnixDatagram::from_std(FromRawFd::from_raw_fd(fd))
}
}

#[cfg(feature = "io_safety")]
impl AsFd for UnixDatagram {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}

#[cfg(feature = "io_safety")]
impl From<OwnedFd> for UnixDatagram {
fn from(fd: OwnedFd) -> UnixDatagram {
UnixDatagram::from_std(fd.into())
}
}

#[cfg(feature = "io_safety")]
impl From<UnixDatagram> for OwnedFd {
fn from(ts: UnixDatagram) -> Self {
ts.inner.into_inner().into()
}
}
23 changes: 23 additions & 0 deletions src/net/uds/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use crate::io_source::IoSource;
use crate::net::{SocketAddr, UnixStream};
use crate::{event, sys, Interest, Registry, Token};

#[cfg(feature = "io_safety")]
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use std::os::unix::net;
use std::path::Path;
Expand Down Expand Up @@ -102,3 +104,24 @@ impl FromRawFd for UnixListener {
UnixListener::from_std(FromRawFd::from_raw_fd(fd))
}
}

#[cfg(feature = "io_safety")]
impl AsFd for UnixListener {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}

#[cfg(feature = "io_safety")]
impl From<OwnedFd> for UnixListener {
fn from(fd: OwnedFd) -> UnixListener {
UnixListener::from_std(fd.into())
}
}

#[cfg(feature = "io_safety")]
impl From<UnixListener> for OwnedFd {
fn from(ts: UnixListener) -> Self {
ts.inner.into_inner().into()
}
}
Loading