refactor daemon polling and event handling

This commit is contained in:
Qyriad 2026-03-22 17:15:04 +01:00
parent d4b40e8cc1
commit 2ecd987be6

View file

@ -10,7 +10,7 @@ use std::{
use iddqd::{BiHashMap, IdOrdMap};
use mio::{Events, Interest, Poll, Token, net::UnixListener, unix::SourceFd};
use mio::{Events, Interest, Poll, Token, event::Event, net::UnixListener, unix::SourceFd};
use rustix::{buffer::spare_capacity, net::SocketFlags, process::Uid};
@ -53,7 +53,8 @@ fn next_token() -> Token {
// If the increment wrapped to 0, then we just increment it again.
if tok == 0 {
return Token(NEXT_TOKEN_NUMBER.fetch_add(1, Ordering::SeqCst));
warn!("File descriptor token wrapped. That's... a lot.");
return next_token();
}
Token(tok)
@ -274,6 +275,7 @@ impl Daemon {
self.fd.as_fd()
}
}
const DAEMON: Token = Token(0);
/// Private helpers.
impl Daemon {
@ -368,7 +370,6 @@ impl Daemon {
);
}
let mut daemon_source = SourceFd(&raw_fd);
const DAEMON: Token = Token(0);
self.tokfd
.insert_unique(TokenFd {
token: DAEMON,
@ -385,15 +386,24 @@ impl Daemon {
loop {
if tracing::enabled!(tracing::Level::DEBUG) {
//
trace!("Daemon loop iteration, with file descriptors: ");
for info in &self.fd_info {
trace!("- {}", info.display());
}
}
match self.poller.poll(&mut events, TIMEOUT_NEVER) {
Ok(_) => {
let poll_result = self.poller.poll(&mut events, TIMEOUT_NEVER);
self.handle_poll(poll_result, &events)?;
}
}
fn handle_poll(
&mut self,
poll_result: Result<(), IoError>,
events: &Events,
) -> Result<(), IoError> {
match poll_result {
Ok(()) => {
trace!(
"mio::Poller::poll() got events: {:?}",
events.iter().size_hint().0,
@ -408,11 +418,12 @@ impl Daemon {
},
Err(e) if e.kind() == IoErrorKind::Interrupted => {
// EINTR is silly.
continue;
// Return early, and poll() again.
return Ok(());
},
Err(e) => {
if let Some(Errno::BADF) = e.raw_os_error().map(Errno::from_raw_os_error) {
unreachable!("EBADF on poller fd; IO safety violation?");
panic!("EBADF on poller fd; IO safety violation?");
}
warn!("mio Poll::poll() error: {e}");
self.fd_error_push(self.poller.as_raw_fd(), e)
@ -422,8 +433,16 @@ impl Daemon {
},
}
for event in &events {
trace!("event is {event:?}");
for event in events {
self.handle_event(event)?;
}
Ok(())
}
fn handle_event(&mut self, event: &Event) -> Result<(), IoError> {
trace!("Handling event {event:?}");
match event.token() {
DAEMON => {
let is_sock = self.main_fd_info().kind == FdKind::Socket;
@ -431,7 +450,8 @@ impl Daemon {
// SAFETY: oh boy: disjoint borrows with extra steps.
let file_fd = unsafe { BorrowedFd::borrow_raw(self.fd.as_raw_fd()) };
self.read_cmd(&file_fd).unwrap();
continue;
return Ok(());
}
// Accept, first.
@ -453,7 +473,8 @@ impl Daemon {
self.fd
)
})?;
continue;
return Ok(());
},
};
@ -467,7 +488,7 @@ impl Daemon {
other_token => {
// This must be a stream fd.
let stream_fd = self.fd_for_token(other_token).unwrap_or_else(|| {
unreachable!("tried to get fd for no-existent token? {other_token:?}")
unreachable!("tried to get fd for non-existent token? {other_token:?}")
});
if event.is_read_closed() {
@ -479,8 +500,8 @@ impl Daemon {
}
},
}
}
}
Ok(())
}
}