mio/sys/unix/waker/
eventfd.rs1use std::fs::File;
2use std::io::{self, Read, Write};
3#[cfg(not(target_os = "hermit"))]
4use std::os::fd::{AsRawFd, FromRawFd, RawFd};
5#[cfg(target_os = "hermit")]
8use std::os::hermit::io::{AsRawFd, FromRawFd, RawFd};
9
10use crate::sys::Selector;
11use crate::{Interest, Token};
12
13#[derive(Debug)]
20pub(crate) struct Waker {
21 fd: File,
22}
23
24impl Waker {
25 #[allow(dead_code)] pub(crate) fn new(selector: &Selector, token: Token) -> io::Result<Waker> {
27 let waker = Waker::new_unregistered()?;
28 selector.register(waker.fd.as_raw_fd(), token, Interest::READABLE)?;
29 Ok(waker)
30 }
31
32 pub(crate) fn new_unregistered() -> io::Result<Waker> {
33 #[cfg(not(target_os = "espidf"))]
34 let flags = libc::EFD_CLOEXEC | libc::EFD_NONBLOCK;
35 #[cfg(target_os = "espidf")]
37 let flags = 0;
38 let fd = syscall!(eventfd(0, flags))?;
39 let file = unsafe { File::from_raw_fd(fd) };
40 Ok(Waker { fd: file })
41 }
42
43 #[allow(clippy::unused_io_amount)] pub(crate) fn wake(&self) -> io::Result<()> {
45 #[cfg(target_os = "illumos")]
50 self.reset()?;
51
52 let buf: [u8; 8] = 1u64.to_ne_bytes();
53 match (&self.fd).write(&buf) {
54 Ok(_) => Ok(()),
55 Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
56 self.reset()?;
59 self.wake()
60 }
61 Err(err) => Err(err),
62 }
63 }
64
65 #[allow(dead_code)] pub(crate) fn ack_and_reset(&self) {
67 let _ = self.reset();
68 }
69
70 #[allow(clippy::unused_io_amount)] fn reset(&self) -> io::Result<()> {
73 let mut buf: [u8; 8] = 0u64.to_ne_bytes();
74 match (&self.fd).read(&mut buf) {
75 Ok(_) => Ok(()),
76 Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => Ok(()),
79 Err(err) => Err(err),
80 }
81 }
82}
83
84impl AsRawFd for Waker {
85 fn as_raw_fd(&self) -> RawFd {
86 self.fd.as_raw_fd()
87 }
88}