From b745565572201301fd6b7d0ebd3bd4b17ee75016 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 5 Jun 2023 20:06:38 -0700 Subject: [PATCH] Breaking change: support creating an `Async` with `AsFd` rather than `AsRawFd` Modify the `Async::new` constructor to use `AsFd` rather than `AsRawFd` (or the socket equivalents on Windows). Modify other code accordingly. Drop impls of `AsRawFd` and `AsRawSocket`. Update inotify dev-dependency to 0.10.1 so that the inotify example still builds. --- Cargo.toml | 2 +- examples/unix-signal.rs | 10 +++++++-- src/lib.rs | 46 ++++++++++++----------------------------- 3 files changed, 22 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9925cf1..cdfcf12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ signal-hook = "0.3" tempfile = "3" [target.'cfg(target_os = "linux")'.dev-dependencies] -inotify = { version = "0.10", default-features = false } +inotify = { version = "0.10.1", default-features = false } timerfd = "1" [target.'cfg(windows)'.dev-dependencies] diff --git a/examples/unix-signal.rs b/examples/unix-signal.rs index e712893..7f262e8 100644 --- a/examples/unix-signal.rs +++ b/examples/unix-signal.rs @@ -8,7 +8,10 @@ #[cfg(unix)] fn main() -> std::io::Result<()> { - use std::os::unix::{io::AsRawFd, net::UnixStream}; + use std::os::unix::{ + io::{AsFd, AsRawFd}, + net::UnixStream, + }; use async_io::Async; use futures_lite::{future, prelude::*}; @@ -16,7 +19,10 @@ fn main() -> std::io::Result<()> { future::block_on(async { // Create a Unix stream that receives a byte on each signal occurrence. let (a, mut b) = Async::::pair()?; - signal_hook::low_level::pipe::register_raw(signal_hook::consts::SIGINT, a.as_raw_fd())?; + signal_hook::low_level::pipe::register_raw( + signal_hook::consts::SIGINT, + a.as_fd().as_raw_fd(), + )?; println!("Waiting for Ctrl-C..."); // Receive a byte that indicates the Ctrl-C signal occurred. diff --git a/src/lib.rs b/src/lib.rs index 2822df9..38cde7d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,7 +66,7 @@ use std::time::{Duration, Instant}; #[cfg(unix)] use std::{ - os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd}, + os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd}, os::unix::net::{SocketAddr as UnixSocketAddr, UnixDatagram, UnixListener, UnixStream}, path::Path, }; @@ -621,14 +621,14 @@ pub struct Async { impl Unpin for Async {} #[cfg(unix)] -impl Async { +impl Async { /// Creates an async I/O handle. /// /// This method will put the handle in non-blocking mode and register it in /// [epoll]/[kqueue]/[event ports]/[IOCP]. /// - /// On Unix systems, the handle must implement `AsRawFd`, while on Windows it must implement - /// `AsRawSocket`. + /// On Unix systems, the handle must implement `AsFd`, while on Windows it must implement + /// `AsSocket`. /// /// [epoll]: https://en.wikipedia.org/wiki/Epoll /// [kqueue]: https://en.wikipedia.org/wiki/Kqueue @@ -647,14 +647,9 @@ impl Async { /// # std::io::Result::Ok(()) }); /// ``` pub fn new(io: T) -> io::Result> { - let raw = io.as_raw_fd(); + let fd = io.as_fd(); // Put the file descriptor in non-blocking mode. - // - // Safety: We assume `as_raw_fd()` returns a valid fd. When we can - // depend on Rust >= 1.63, where `AsFd` is stabilized, and when - // `TimerFd` implements it, we can remove this unsafe and simplify this. - let fd = unsafe { rustix::fd::BorrowedFd::borrow_raw(raw) }; cfg_if::cfg_if! { // ioctl(FIONBIO) sets the flag atomically, but we use this only on Linux // for now, as with the standard library, because it seems to behave @@ -674,19 +669,12 @@ impl Async { } Ok(Async { - source: Reactor::get().insert_io(raw)?, + source: Reactor::get().insert_io(fd.as_raw_fd())?, io: Some(io), }) } } -#[cfg(unix)] -impl AsRawFd for Async { - fn as_raw_fd(&self) -> RawFd { - self.get_ref().as_raw_fd() - } -} - #[cfg(unix)] impl AsFd for Async { fn as_fd(&self) -> BorrowedFd<'_> { @@ -695,7 +683,7 @@ impl AsFd for Async { } #[cfg(unix)] -impl> TryFrom for Async { +impl> TryFrom for Async { type Error = io::Error; fn try_from(value: OwnedFd) -> Result { @@ -713,14 +701,14 @@ impl> TryFrom> for OwnedFd { } #[cfg(windows)] -impl Async { +impl Async { /// Creates an async I/O handle. /// /// This method will put the handle in non-blocking mode and register it in /// [epoll]/[kqueue]/[event ports]/[IOCP]. /// - /// On Unix systems, the handle must implement `AsRawFd`, while on Windows it must implement - /// `AsRawSocket`. + /// On Unix systems, the handle must implement `AsFd`, while on Windows it must implement + /// `AsSocket`. /// /// [epoll]: https://en.wikipedia.org/wiki/Epoll /// [kqueue]: https://en.wikipedia.org/wiki/Kqueue @@ -739,8 +727,7 @@ impl Async { /// # std::io::Result::Ok(()) }); /// ``` pub fn new(io: T) -> io::Result> { - let sock = io.as_raw_socket(); - let borrowed = unsafe { rustix::fd::BorrowedFd::borrow_raw(sock) }; + let borrowed = io.as_socket(); // Put the socket in non-blocking mode. // @@ -750,19 +737,12 @@ impl Async { rustix::io::ioctl_fionbio(borrowed, true)?; Ok(Async { - source: Reactor::get().insert_io(sock)?, + source: Reactor::get().insert_io(borrowed.as_raw_socket())?, io: Some(io), }) } } -#[cfg(windows)] -impl AsRawSocket for Async { - fn as_raw_socket(&self) -> RawSocket { - self.get_ref().as_raw_socket() - } -} - #[cfg(windows)] impl AsSocket for Async { fn as_socket(&self) -> BorrowedSocket<'_> { @@ -771,7 +751,7 @@ impl AsSocket for Async { } #[cfg(windows)] -impl> TryFrom for Async { +impl> TryFrom for Async { type Error = io::Error; fn try_from(value: OwnedSocket) -> Result {