async_io/os/unix.rs
1//! Functionality that is only available for `unix` platforms.
2
3use std::os::unix::io::BorrowedFd;
4
5/// Get a file descriptor that can be used to wait for readiness in an external runtime.
6///
7/// This file descriptor is equivalent to the one used by the underlying epoll/kqueue/event ports
8/// instance for polling. The intention is that this file descriptor can be registered into an
9/// external runtime (like [`calloop`] or [GLib]) so that `async-io` can be seamlessly polled
10/// alongside the other runtime.
11///
12/// Not every backend used on `unix` has an associated file descriptor, however. While epoll,
13/// kqueue and event ports have a file descriptor as a backend, on some Unix systems `async-io`
14/// will use the `poll()` system call instead. Since there are no file descriptors intrinsically
15/// associated with `poll()`, this function will return `None`.
16///
17/// There is presently no way to stop the "`async-io`" thread from being launched, so the reactor
18/// will still be continuously polled on that thread. This fact should be kept in mind by anyone
19/// looking to integrate `async-io` into another runtime using this function.
20///
21/// It is possible to use this function to call raw system calls on the underlying event source.
22/// This is generally not recommended, since registered event sources may conflict with `async-io`'s
23/// existing scheme for managing sources. The behavior resulting from this is not specified, but
24/// will not result in undefined behavior. This could include panics, incorrect results, aborts,
25/// memory leaks, and non-termination.
26///
27/// [`calloop`]: https://docs.rs/calloop
28/// [GLib]: https://en.wikipedia.org/wiki/GLib
29///
30/// ## Example
31///
32/// ```
33/// #![cfg(unix)]
34///
35/// use async_io::os::unix::reactor_fd;
36///
37/// my_runtime::register(reactor_fd().unwrap());
38/// # mod my_runtime {
39/// # use std::os::unix::io::BorrowedFd;
40/// # pub fn register(_: BorrowedFd<'_>) {}
41/// # }
42/// ```
43pub fn reactor_fd() -> Option<BorrowedFd<'static>> {
44 cfg_if::cfg_if! {
45 if #[cfg(all(
46 any(
47 target_os = "linux",
48 target_os = "android",
49 target_os = "illumos",
50 target_os = "solaris",
51 target_vendor = "apple",
52 target_os = "freebsd",
53 target_os = "netbsd",
54 target_os = "openbsd",
55 target_os = "dragonfly",
56 ),
57 not(polling_test_poll_backend),
58 ))] {
59 use std::os::unix::io::AsFd;
60 Some(crate::Reactor::get().poller.as_fd())
61 } else {
62 None
63 }
64 }
65}