From 70869a7a576e8073abc9d48936f7efc088e5b284 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Thu, 6 Apr 2023 15:48:43 -0700 Subject: [PATCH 1/4] Add a way to get the global poller's fd --- src/os.rs | 3 +++ src/os/unix.rs | 33 +++++++++++++++++++++++++++++++++ src/reactor.rs | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/os/unix.rs diff --git a/src/os.rs b/src/os.rs index 5db3c57..7561849 100644 --- a/src/os.rs +++ b/src/os.rs @@ -1,5 +1,8 @@ //! Platform-specific functionality. +#[cfg(unix)] +pub mod unix; + #[cfg(any( target_os = "macos", target_os = "ios", diff --git a/src/os/unix.rs b/src/os/unix.rs new file mode 100644 index 0000000..2f4548b --- /dev/null +++ b/src/os/unix.rs @@ -0,0 +1,33 @@ +//! Functionality that is only available for `unix` platforms. + +#[cfg(not(async_io_no_io_safety))] +use std::os::unix::io::BorrowedFd; + +/// Get a file descriptor that can be used to wait for readiness in an external runtime. +#[cfg(not(async_io_no_io_safety))] +pub fn reactor_fd() -> Option> { + cfg_if::cfg_if! { + if #[cfg(all( + any( + target_os = "linux", + target_os = "android", + target_os = "illumos", + target_os = "solaris", + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "dragonfly", + ), + not(polling_test_poll_backend), + ))] { + use std::os::unix::io::AsFd; + Some(crate::Reactor::get().poller.as_fd()) + } else { + None + } + } +} diff --git a/src/reactor.rs b/src/reactor.rs index c2958f0..e3ae287 100644 --- a/src/reactor.rs +++ b/src/reactor.rs @@ -53,7 +53,7 @@ pub(crate) struct Reactor { /// Portable bindings to epoll/kqueue/event ports/IOCP. /// /// This is where I/O is polled, producing I/O events. - poller: Poller, + pub(crate) poller: Poller, /// Ticker bumped before polling. /// From b6217299d9af6eb9fe1791ac05a6905251c6c430 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Thu, 6 Apr 2023 15:58:30 -0700 Subject: [PATCH 2/4] Add more documentation --- src/os/unix.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/os/unix.rs b/src/os/unix.rs index 2f4548b..d11b37b 100644 --- a/src/os/unix.rs +++ b/src/os/unix.rs @@ -4,6 +4,40 @@ use std::os::unix::io::BorrowedFd; /// Get a file descriptor that can be used to wait for readiness in an external runtime. +/// +/// This file descriptor is equivalent to the one used by the underlying epoll/kqueue/event ports +/// instance for polling. The intention is that this file descriptor can be registered into an +/// external runtime (like [`calloop`] or GLib) so that `async-io` can be seamlessly polled +/// alongside the other runtime. +/// +/// Not every backend used on `unix` has an associated file descriptor, however. While epoll, +/// kqueue and event ports have a file descriptor as a backend, on some Unix systems `async-io` +/// will use the `poll()` system call instead. Since there are no file descriptors intrinsically +/// associated with `poll()`, this function will return `None`. +/// +/// There is presently no way to stop the "`async-io`" thread from being launched, so the reactor +/// will still be continiously polled on that thread. This fact should be kept in mind by anyone +/// looking to integrate `async-io` into another runtime using this function. +/// +/// It is possible to use this function to call raw system calls on the underlying event source. +/// This is generally not recommended, since registered event sources may conflict with `async-io`'s +/// existing scheme for managing sources. The behavior resulting from this is not specified, but +/// will not result in undefined behavior. This could include panics, incorrect results, aborts, +/// memory leaks, and non-termination. +/// +/// ## Example +/// +/// ``` +/// #![cfg(unix)] +/// +/// use async_io::os::unix::reactor_fd; +/// +/// my_runtime::register(reactor_fd()); +/// # mod my_runtime { +/// # use std::os::unix::io::BorrowedFd; +/// # fn register(_: BorrowedFd<'_>) {} +/// # } +/// ``` #[cfg(not(async_io_no_io_safety))] pub fn reactor_fd() -> Option> { cfg_if::cfg_if! { From 3283a88d8683710dea9635aa852dc93099b858e3 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Thu, 6 Apr 2023 16:06:49 -0700 Subject: [PATCH 3/4] Fix doctest --- src/os/unix.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/os/unix.rs b/src/os/unix.rs index d11b37b..5f0c6f2 100644 --- a/src/os/unix.rs +++ b/src/os/unix.rs @@ -32,10 +32,10 @@ use std::os::unix::io::BorrowedFd; /// /// use async_io::os::unix::reactor_fd; /// -/// my_runtime::register(reactor_fd()); +/// my_runtime::register(reactor_fd().unwrap()); /// # mod my_runtime { /// # use std::os::unix::io::BorrowedFd; -/// # fn register(_: BorrowedFd<'_>) {} +/// # pub fn register(_: BorrowedFd<'_>) {} /// # } /// ``` #[cfg(not(async_io_no_io_safety))] From 8c5773b6caaf905436078dcb2023d53f0e8aebd2 Mon Sep 17 00:00:00 2001 From: jtnunley Date: Sun, 9 Apr 2023 14:33:16 -0700 Subject: [PATCH 4/4] Fix doclinks --- src/os/unix.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/os/unix.rs b/src/os/unix.rs index 5f0c6f2..ffb0832 100644 --- a/src/os/unix.rs +++ b/src/os/unix.rs @@ -7,7 +7,7 @@ use std::os::unix::io::BorrowedFd; /// /// This file descriptor is equivalent to the one used by the underlying epoll/kqueue/event ports /// instance for polling. The intention is that this file descriptor can be registered into an -/// external runtime (like [`calloop`] or GLib) so that `async-io` can be seamlessly polled +/// external runtime (like [`calloop`] or [GLib]) so that `async-io` can be seamlessly polled /// alongside the other runtime. /// /// Not every backend used on `unix` has an associated file descriptor, however. While epoll, @@ -25,6 +25,9 @@ use std::os::unix::io::BorrowedFd; /// will not result in undefined behavior. This could include panics, incorrect results, aborts, /// memory leaks, and non-termination. /// +/// [`calloop`]: https://docs.rs/calloop +/// [GLib]: https://en.wikipedia.org/wiki/GLib +/// /// ## Example /// /// ```