diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1fe3b25..304ecfc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,6 +117,10 @@ jobs: run: | rustup target add x86_64-unknown-illumos cargo build --target x86_64-unknown-illumos + - name: Redox + run: | + rustup target add x86_64-unknown-redox + cargo check --target x86_64-unknown-redox wine: runs-on: ubuntu-22.04 diff --git a/Cargo.toml b/Cargo.toml index 57f7efd..085f13d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ cfg-if = "1" tracing = { version = "0.1.37", default-features = false } [target.'cfg(any(unix, target_os = "fuchsia", target_os = "vxworks"))'.dependencies] -rustix = { version = "0.38.8", features = ["event", "fs", "pipe", "process", "std", "time"], default-features = false } +rustix = { version = "0.38.31", features = ["event", "fs", "pipe", "process", "std", "time"], default-features = false } [target.'cfg(windows)'.dependencies] concurrent-queue = "2.2.0" diff --git a/src/epoll.rs b/src/epoll.rs index 93afab0..2f1a661 100644 --- a/src/epoll.rs +++ b/src/epoll.rs @@ -4,16 +4,20 @@ use std::io; use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}; use std::time::Duration; -use rustix::event::{epoll, eventfd, EventfdFlags}; -use rustix::fd::OwnedFd; -use rustix::fs::{fcntl_getfl, fcntl_setfl, OFlags}; -use rustix::io::{fcntl_getfd, fcntl_setfd, read, write, FdFlags}; -use rustix::pipe::{pipe, pipe_with, PipeFlags}; +#[cfg(not(target_os = "redox"))] +use rustix::event::{eventfd, EventfdFlags}; +#[cfg(not(target_os = "redox"))] use rustix::time::{ timerfd_create, timerfd_settime, Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags, Timespec, }; +use rustix::event::epoll; +use rustix::fd::OwnedFd; +use rustix::fs::{fcntl_getfl, fcntl_setfl, OFlags}; +use rustix::io::{fcntl_getfd, fcntl_setfd, read, write, FdFlags}; +use rustix::pipe::{pipe, pipe_with, PipeFlags}; + use crate::{Event, PollMode}; /// Interface to epoll. @@ -26,6 +30,9 @@ pub struct Poller { notifier: Notifier, /// File descriptor for the timerfd that produces timeouts. + /// + /// Redox does not support timerfd. + #[cfg(not(target_os = "redox"))] timer_fd: Option, } @@ -39,6 +46,7 @@ impl Poller { // Set up notifier and timerfd. let notifier = Notifier::new()?; + #[cfg(not(target_os = "redox"))] let timer_fd = timerfd_create( TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC | TimerfdFlags::NONBLOCK, @@ -48,10 +56,12 @@ impl Poller { let poller = Poller { epoll_fd, notifier, + #[cfg(not(target_os = "redox"))] timer_fd, }; unsafe { + #[cfg(not(target_os = "redox"))] if let Some(ref timer_fd) = poller.timer_fd { poller.add( timer_fd.as_raw_fd(), @@ -70,7 +80,6 @@ impl Poller { tracing::trace!( epoll_fd = ?poller.epoll_fd.as_raw_fd(), notifier = ?poller.notifier, - timer_fd = ?poller.timer_fd, "new", ); Ok(poller) @@ -155,6 +164,7 @@ impl Poller { ); let _enter = span.enter(); + #[cfg(not(target_os = "redox"))] if let Some(ref timer_fd) = self.timer_fd { // Configure the timeout using timerfd. let new_val = Itimerspec { @@ -181,8 +191,13 @@ impl Poller { )?; } + #[cfg(not(target_os = "redox"))] + let timer_fd = &self.timer_fd; + #[cfg(target_os = "redox")] + let timer_fd: Option = None; + // Timeout in milliseconds for epoll. - let timeout_ms = match (&self.timer_fd, timeout) { + let timeout_ms = match (timer_fd, timeout) { (_, Some(t)) if t == Duration::from_secs(0) => 0, (None, Some(t)) => { // Round up to a whole millisecond. @@ -245,10 +260,10 @@ impl Drop for Poller { "drop", epoll_fd = ?self.epoll_fd.as_raw_fd(), notifier = ?self.notifier, - timer_fd = ?self.timer_fd ); let _enter = span.enter(); + #[cfg(not(target_os = "redox"))] if let Some(timer_fd) = self.timer_fd.take() { let _ = self.delete(timer_fd.as_fd()); } @@ -257,6 +272,7 @@ impl Drop for Poller { } /// `timespec` value that equals zero. +#[cfg(not(target_os = "redox"))] const TS_ZERO: Timespec = unsafe { std::mem::transmute([0u8; std::mem::size_of::()]) }; /// Get the EPOLL flags for the interest. @@ -390,6 +406,7 @@ impl EventExtra { #[derive(Debug)] enum Notifier { /// The primary notifier, using eventfd. + #[cfg(not(target_os = "redox"))] EventFd(OwnedFd), /// The fallback notifier, using a pipe. @@ -406,19 +423,22 @@ impl Notifier { /// Create a new notifier. fn new() -> io::Result { // Skip eventfd for testing if necessary. - if !cfg!(polling_test_epoll_pipe) { - // Try to create an eventfd. - match eventfd(0, EventfdFlags::CLOEXEC | EventfdFlags::NONBLOCK) { - Ok(fd) => { - tracing::trace!("created eventfd for notifier"); - return Ok(Notifier::EventFd(fd)); - } + #[cfg(not(target_os = "redox"))] + { + if !cfg!(polling_test_epoll_pipe) { + // Try to create an eventfd. + match eventfd(0, EventfdFlags::CLOEXEC | EventfdFlags::NONBLOCK) { + Ok(fd) => { + tracing::trace!("created eventfd for notifier"); + return Ok(Notifier::EventFd(fd)); + } - Err(err) => { - tracing::warn!( - "eventfd() failed with error ({}), falling back to pipe", - err - ); + Err(err) => { + tracing::warn!( + "eventfd() failed with error ({}), falling back to pipe", + err + ); + } } } } @@ -440,6 +460,7 @@ impl Notifier { /// The file descriptor to register in the poller. fn as_fd(&self) -> BorrowedFd<'_> { match self { + #[cfg(not(target_os = "redox"))] Notifier::EventFd(fd) => fd.as_fd(), Notifier::Pipe { read_pipe: read, .. @@ -450,6 +471,7 @@ impl Notifier { /// Notify the poller. fn notify(&self) { match self { + #[cfg(not(target_os = "redox"))] Self::EventFd(fd) => { let buf: [u8; 8] = 1u64.to_ne_bytes(); let _ = write(fd, &buf); @@ -464,6 +486,7 @@ impl Notifier { /// Clear the notification. fn clear(&self) { match self { + #[cfg(not(target_os = "redox"))] Self::EventFd(fd) => { let mut buf = [0u8; 8]; let _ = read(fd, &mut buf); diff --git a/src/lib.rs b/src/lib.rs index 9257f05..271ca41 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ //! Portable interface to epoll, kqueue, event ports, and IOCP. //! //! Supported platforms: -//! - [epoll](https://en.wikipedia.org/wiki/Epoll): Linux, Android +//! - [epoll](https://en.wikipedia.org/wiki/Epoll): Linux, Android, RedoxOS //! - [kqueue](https://en.wikipedia.org/wiki/Kqueue): macOS, iOS, tvOS, watchOS, FreeBSD, NetBSD, OpenBSD, //! DragonFly BSD //! - [event ports](https://illumos.org/man/port_create): illumos, Solaris @@ -80,7 +80,11 @@ cfg_if! { if #[cfg(polling_test_poll_backend)] { mod poll; use poll as sys; - } else if #[cfg(any(target_os = "linux", target_os = "android"))] { + } else if #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "redox" + ))] { mod epoll; use epoll as sys; } else if #[cfg(any( diff --git a/src/os.rs b/src/os.rs index 2a5d6e6..1d58bfa 100644 --- a/src/os.rs +++ b/src/os.rs @@ -20,6 +20,7 @@ pub mod iocp; mod __private { #[doc(hidden)] + #[allow(dead_code)] pub trait PollerSealed {} impl PollerSealed for crate::Poller {}