Created
August 7, 2024 05:13
-
-
Save sunshowers/c573ae448d2c1eb028216c3f3d644719 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/sys/unix/mod.rs b/src/sys/unix/mod.rs | |
index cfbd525d28...47ef234cca 100644 | |
--- a/src/sys/unix/mod.rs | |
+++ b/src/sys/unix/mod.rs | |
@@ -54,6 +54,18 @@ | |
#[cfg_attr(all( | |
not(mio_unsupported_force_waker_pipe), | |
any( | |
+ target_os = "android", | |
+ target_os = "espidf", | |
+ target_os = "fuchsia", | |
+ target_os = "hermit", | |
+ target_os = "illumos", | |
+ target_os = "linux", | |
+ ) | |
+ ), path = "waker/eventfd.rs")] | |
+ #[cfg_attr(all( | |
+ not(mio_unsupported_force_waker_pipe), | |
+ not(mio_unsupported_force_poll_poll), // `kqueue(2)` based waker doesn't work with `poll(2)`. | |
+ any( | |
target_os = "freebsd", | |
target_os = "ios", | |
target_os = "macos", | |
@@ -62,8 +74,34 @@ | |
target_os = "watchos", | |
) | |
), path = "waker/kqueue.rs")] | |
+ #[cfg_attr(any( | |
+ // NOTE: also add to the list list for the `pipe` module below. | |
+ mio_unsupported_force_waker_pipe, | |
+ all( | |
+ // `kqueue(2)` based waker doesn't work with `poll(2)`. | |
+ mio_unsupported_force_poll_poll, | |
+ any( | |
+ target_os = "freebsd", | |
+ target_os = "ios", | |
+ target_os = "macos", | |
+ target_os = "tvos", | |
+ target_os = "visionos", | |
+ target_os = "watchos", | |
+ ), | |
+ ), | |
+ target_os = "aix", | |
+ target_os = "dragonfly", | |
+ target_os = "haiku", | |
+ target_os = "netbsd", | |
+ target_os = "nto", | |
+ target_os = "openbsd", | |
+ target_os = "redox", | |
+ target_os = "solaris", | |
+ target_os = "vita", | |
+ ), path = "waker/pipe.rs")] | |
mod waker; | |
- pub(crate) use self::waker::Waker; | |
+ // NOTE: the `Waker` type is expected in the selector module as the | |
+ // `poll(2)` implementation needs to do some special stuff. | |
mod sourcefd; | |
#[cfg(feature = "os-ext")] | |
@@ -83,10 +121,22 @@ | |
all(feature = "os-ext", not(target_os = "hermit")), | |
// For the `Waker` type based on a pipe. | |
mio_unsupported_force_waker_pipe, | |
+ all( | |
+ // `kqueue(2)` based waker doesn't work with `poll(2)`. | |
+ mio_unsupported_force_poll_poll, | |
+ any( | |
+ target_os = "freebsd", | |
+ target_os = "ios", | |
+ target_os = "macos", | |
+ target_os = "tvos", | |
+ target_os = "visionos", | |
+ target_os = "watchos", | |
+ ), | |
+ ), | |
+ // NOTE: also add to the list list for the `pipe` module below. | |
target_os = "aix", | |
target_os = "dragonfly", | |
target_os = "haiku", | |
- target_os = "illumos", | |
target_os = "netbsd", | |
target_os = "nto", | |
target_os = "openbsd", | |
diff --git a/src/sys/unix/selector/epoll.rs b/src/sys/unix/selector/epoll.rs | |
index 0487dc2e87...082a65871a 100644 | |
--- a/src/sys/unix/selector/epoll.rs | |
+++ b/src/sys/unix/selector/epoll.rs | |
@@ -222,7 +222,10 @@ | |
} | |
} | |
+// No special requirement from the implementation around waking. | |
+pub(crate) use crate::sys::unix::waker::Waker; | |
+ | |
cfg_io_source! { | |
mod stateless_io_source; | |
pub(crate) use stateless_io_source::IoSourceState; | |
} | |
diff --git a/src/sys/unix/selector/kqueue.rs b/src/sys/unix/selector/kqueue.rs | |
index d30b06e831...f31db35fb0 100644 | |
--- a/src/sys/unix/selector/kqueue.rs | |
+++ b/src/sys/unix/selector/kqueue.rs | |
@@ -868,6 +868,9 @@ | |
} | |
} | |
+// No special requirement from the implementation around waking. | |
+pub(crate) use crate::sys::unix::waker::Waker; | |
+ | |
cfg_io_source! { | |
mod stateless_io_source; | |
pub(crate) use stateless_io_source::IoSourceState; | |
diff --git a/src/sys/unix/selector/poll.rs b/src/sys/unix/selector/poll.rs | |
index ee4f50a7e3...ac282c6275 100644 | |
--- a/src/sys/unix/selector/poll.rs | |
+++ b/src/sys/unix/selector/poll.rs | |
@@ -16,7 +16,7 @@ | |
use std::time::Duration; | |
use std::{cmp, fmt, io}; | |
-use crate::sys::unix::waker::WakerInternal; | |
+use crate::sys::unix::waker::Waker as WakerInternal; | |
use crate::{Interest, Token}; | |
/// Unique id for use as `SelectorId`. | |
@@ -161,7 +161,7 @@ | |
impl SelectorState { | |
pub fn new() -> io::Result<SelectorState> { | |
- let notify_waker = WakerInternal::new()?; | |
+ let notify_waker = WakerInternal::new_unregistered()?; | |
Ok(Self { | |
fds: Mutex::new(Fds { | |
@@ -625,6 +625,25 @@ | |
} | |
} | |
+#[derive(Debug)] | |
+pub(crate) struct Waker { | |
+ selector: Selector, | |
+ token: Token, | |
+} | |
+ | |
+impl Waker { | |
+ pub(crate) fn new(selector: &Selector, token: Token) -> io::Result<Waker> { | |
+ Ok(Waker { | |
+ selector: selector.try_clone()?, | |
+ token, | |
+ }) | |
+ } | |
+ | |
+ pub(crate) fn wake(&self) -> io::Result<()> { | |
+ self.selector.wake(self.token) | |
+ } | |
+} | |
+ | |
cfg_io_source! { | |
use crate::Registry; | |
diff --git a/src/sys/unix/waker/eventfd.rs b/src/sys/unix/waker/eventfd.rs | |
index 2b53d1c56a...c0086fce9c 100644 | |
--- a/src/sys/unix/waker/eventfd.rs | |
+++ b/src/sys/unix/waker/eventfd.rs | |
@@ -7,6 +7,9 @@ | |
#[cfg(target_os = "hermit")] | |
use std::os::hermit::io::{AsRawFd, FromRawFd, RawFd}; | |
+use crate::sys::Selector; | |
+use crate::{Interest, Token}; | |
+ | |
/// Waker backed by `eventfd`. | |
/// | |
/// `eventfd` is effectively an 64 bit counter. All writes must be of 8 | |
@@ -19,14 +22,20 @@ | |
} | |
impl Waker { | |
- pub(crate) fn new() -> io::Result<Waker> { | |
+ #[allow(dead_code)] // Not used by the `poll(2)` implementation. | |
+ pub(crate) fn new(selector: &Selector, token: Token) -> io::Result<Waker> { | |
+ let waker = Waker::new_unregistered()?; | |
+ selector.register(waker.fd.as_raw_fd(), token, Interest::READABLE)?; | |
+ Ok(waker) | |
+ } | |
+ | |
+ pub(crate) fn new_unregistered() -> io::Result<Waker> { | |
#[cfg(not(target_os = "espidf"))] | |
let flags = libc::EFD_CLOEXEC | libc::EFD_NONBLOCK; | |
// ESP-IDF is EFD_NONBLOCK by default and errors if you try to pass this flag. | |
#[cfg(target_os = "espidf")] | |
let flags = 0; | |
let fd = syscall!(eventfd(0, flags))?; | |
- | |
let file = unsafe { File::from_raw_fd(fd) }; | |
Ok(Waker { fd: file }) | |
} | |
@@ -46,12 +55,7 @@ | |
} | |
} | |
- #[cfg(any( | |
- mio_unsupported_force_poll_poll, | |
- target_os = "espidf", | |
- target_os = "fuchsia", | |
- target_os = "hermit", | |
- ))] | |
+ #[allow(dead_code)] // Only used by the `poll(2)` implementation. | |
pub(crate) fn ack_and_reset(&self) { | |
let _ = self.reset(); | |
} | |
diff --git a/src/sys/unix/waker/pipe.rs b/src/sys/unix/waker/pipe.rs | |
index ab001849a6...a0a3acff68 100644 | |
--- a/src/sys/unix/waker/pipe.rs | |
+++ b/src/sys/unix/waker/pipe.rs | |
@@ -8,6 +8,8 @@ | |
use std::os::hermit::io::{AsRawFd, FromRawFd, RawFd}; | |
use crate::sys::unix::pipe; | |
+use crate::sys::Selector; | |
+use crate::{Interest, Token}; | |
/// Waker backed by a unix pipe. | |
/// | |
@@ -20,7 +22,14 @@ | |
} | |
impl Waker { | |
- pub(crate) fn new() -> io::Result<Waker> { | |
+ #[allow(dead_code)] // Not used by the `poll(2)` implementation. | |
+ pub(crate) fn new(selector: &Selector, token: Token) -> io::Result<Waker> { | |
+ let waker = Waker::new_unregistered()?; | |
+ selector.register(waker.receiver.as_raw_fd(), token, Interest::READABLE)?; | |
+ Ok(waker) | |
+ } | |
+ | |
+ pub(crate) fn new_unregistered() -> io::Result<Waker> { | |
let [receiver, sender] = pipe::new_raw()?; | |
let sender = unsafe { File::from_raw_fd(sender) }; | |
let receiver = unsafe { File::from_raw_fd(receiver) }; | |
@@ -47,14 +56,7 @@ | |
} | |
} | |
- #[cfg(any( | |
- mio_unsupported_force_poll_poll, | |
- target_os = "espidf", | |
- target_os = "haiku", | |
- target_os = "nto", | |
- target_os = "solaris", | |
- target_os = "vita", | |
- ))] | |
+ #[allow(dead_code)] // Only used by the `poll(2)` implementation. | |
pub(crate) fn ack_and_reset(&self) { | |
self.empty(); | |
} | |
diff --git a/src/sys/unix/waker.rs b/src/sys/unix/waker.rs | |
deleted file mode 100644 | |
index f97b1ebafe..0000000000 | |
--- a/src/sys/unix/waker.rs | |
+++ /dev/null | |
@@ -1,188 +1,0 @@ | |
-#[cfg(all( | |
- not(mio_unsupported_force_poll_poll), | |
- not(all( | |
- not(mio_unsupported_force_waker_pipe), | |
- any( | |
- target_os = "freebsd", | |
- target_os = "ios", | |
- target_os = "macos", | |
- target_os = "tvos", | |
- target_os = "visionos", | |
- target_os = "watchos", | |
- ) | |
- )), | |
- not(any( | |
- target_os = "espidf", | |
- target_os = "haiku", | |
- target_os = "hermit", | |
- target_os = "nto", | |
- target_os = "solaris", | |
- target_os = "vita" | |
- )), | |
-))] | |
-mod fdbased { | |
- use std::io; | |
- use std::os::fd::AsRawFd; | |
- | |
- #[cfg(all( | |
- not(mio_unsupported_force_waker_pipe), | |
- any(target_os = "android", target_os = "fuchsia", target_os = "linux"), | |
- ))] | |
- use crate::sys::unix::waker::eventfd::Waker as WakerInternal; | |
- #[cfg(any( | |
- mio_unsupported_force_waker_pipe, | |
- target_os = "aix", | |
- target_os = "dragonfly", | |
- target_os = "illumos", | |
- target_os = "netbsd", | |
- target_os = "openbsd", | |
- target_os = "redox", | |
- ))] | |
- use crate::sys::unix::waker::pipe::Waker as WakerInternal; | |
- use crate::sys::Selector; | |
- use crate::{Interest, Token}; | |
- | |
- #[derive(Debug)] | |
- pub(crate) struct Waker { | |
- waker: WakerInternal, | |
- } | |
- | |
- impl Waker { | |
- pub(crate) fn new(selector: &Selector, token: Token) -> io::Result<Waker> { | |
- let waker = WakerInternal::new()?; | |
- selector.register(waker.as_raw_fd(), token, Interest::READABLE)?; | |
- Ok(Waker { waker }) | |
- } | |
- | |
- pub(crate) fn wake(&self) -> io::Result<()> { | |
- self.waker.wake() | |
- } | |
- } | |
-} | |
- | |
-#[cfg(all( | |
- not(mio_unsupported_force_poll_poll), | |
- not(all( | |
- not(mio_unsupported_force_waker_pipe), | |
- any( | |
- target_os = "freebsd", | |
- target_os = "ios", | |
- target_os = "macos", | |
- target_os = "tvos", | |
- target_os = "visionos", | |
- target_os = "watchos", | |
- ) | |
- )), | |
- not(any( | |
- target_os = "espidf", | |
- target_os = "haiku", | |
- target_os = "hermit", | |
- target_os = "nto", | |
- target_os = "solaris", | |
- target_os = "vita" | |
- )), | |
-))] | |
-pub(crate) use self::fdbased::Waker; | |
- | |
-#[cfg(all( | |
- not(mio_unsupported_force_waker_pipe), | |
- any( | |
- target_os = "android", | |
- target_os = "espidf", | |
- target_os = "fuchsia", | |
- target_os = "hermit", | |
- target_os = "linux", | |
- ) | |
-))] | |
-mod eventfd; | |
- | |
-#[cfg(all( | |
- not(mio_unsupported_force_waker_pipe), | |
- any( | |
- mio_unsupported_force_poll_poll, | |
- target_os = "espidf", | |
- target_os = "fuchsia", | |
- target_os = "hermit", | |
- ) | |
-))] | |
-pub(crate) use self::eventfd::Waker as WakerInternal; | |
- | |
-#[cfg(any( | |
- mio_unsupported_force_waker_pipe, | |
- target_os = "aix", | |
- target_os = "dragonfly", | |
- target_os = "haiku", | |
- target_os = "illumos", | |
- target_os = "netbsd", | |
- target_os = "nto", | |
- target_os = "openbsd", | |
- target_os = "redox", | |
- target_os = "solaris", | |
- target_os = "vita", | |
-))] | |
-mod pipe; | |
- | |
-#[cfg(any( | |
- all( | |
- mio_unsupported_force_poll_poll, | |
- any( | |
- mio_unsupported_force_waker_pipe, | |
- target_os = "aix", | |
- target_os = "dragonfly", | |
- target_os = "illumos", | |
- target_os = "netbsd", | |
- target_os = "openbsd", | |
- target_os = "redox", | |
- ) | |
- ), | |
- target_os = "haiku", | |
- target_os = "nto", | |
- target_os = "solaris", | |
- target_os = "vita", | |
-))] | |
-pub(crate) use self::pipe::Waker as WakerInternal; | |
- | |
-#[cfg(any( | |
- mio_unsupported_force_poll_poll, | |
- target_os = "espidf", | |
- target_os = "haiku", | |
- target_os = "hermit", | |
- target_os = "nto", | |
- target_os = "solaris", | |
- target_os = "vita", | |
-))] | |
-mod poll { | |
- use crate::sys::Selector; | |
- use crate::Token; | |
- use std::io; | |
- | |
- #[derive(Debug)] | |
- pub(crate) struct Waker { | |
- selector: Selector, | |
- token: Token, | |
- } | |
- | |
- impl Waker { | |
- pub(crate) fn new(selector: &Selector, token: Token) -> io::Result<Waker> { | |
- Ok(Waker { | |
- selector: selector.try_clone()?, | |
- token, | |
- }) | |
- } | |
- | |
- pub(crate) fn wake(&self) -> io::Result<()> { | |
- self.selector.wake(self.token) | |
- } | |
- } | |
-} | |
- | |
-#[cfg(any( | |
- mio_unsupported_force_poll_poll, | |
- target_os = "espidf", | |
- target_os = "haiku", | |
- target_os = "hermit", | |
- target_os = "nto", | |
- target_os = "solaris", | |
- target_os = "vita", | |
-))] | |
-pub(crate) use self::poll::Waker; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment