track poller and daemon fds like the rest

This commit is contained in:
Qyriad 2026-03-19 20:44:57 +01:00
parent aee8dcb31a
commit b11627d030
3 changed files with 271 additions and 82 deletions

View file

@ -1,8 +1,114 @@
use std::os::fd::RawFd;
use std::{os::fd::RawFd, sync::OnceLock};
use iddqd::BiHashItem;
use circular_buffer::CircularBuffer;
use iddqd::{BiHashItem, IdOrdItem};
use mio::Token;
use crate::prelude::*;
const ERROR_BUFFER_LEN: usize = 8;
#[derive(Debug)]
pub struct FdInfo {
pub fd: RawFd,
pub kind: FdKind,
pub name: OnceLock<Box<OsStr>>,
pub error_buffer: CircularBuffer<ERROR_BUFFER_LEN, IoError>,
}
impl FdInfo {
pub fn new<Fd: AsRawFd>(fd: Fd, kind: FdKind) -> Self {
Self {
fd: fd.as_raw_fd(),
kind,
name: Default::default(),
error_buffer: Default::default(),
}
}
pub fn new_with_name<Fd: AsRawFd>(fd: Fd, kind: FdKind, name: Box<OsStr>) -> Self {
Self {
fd: fd.as_raw_fd(),
kind,
name: OnceLock::from(name),
error_buffer: Default::default(),
}
}
}
impl FdInfo {
pub(crate) fn guess_name<Fd: AsRawFd>(fd: Fd) -> Result<Box<OsStr>, IoError> {
let dev_fd_path = Path::new("/dev/fd").join(fd.as_raw_fd().to_string());
fs_err::read_link(dev_fd_path)
.map(PathBuf::into_os_string)
.map(OsString::into_boxed_os_str)
}
pub fn name(&self) -> &OsStr {
if let Some(name) = self.name.get() {
return name;
}
match Self::guess_name(self.fd) {
Ok(name) => {
let prev = self.name.set(Box::from(name));
debug_assert_eq!(prev, Ok(()));
},
Err(e) => {
warn!(
"can't read link for {} /dev/fd/{}: {e}",
self.kind.name_str(),
self.fd,
);
return OsStr::new("«unknown»");
},
}
self.name.get().unwrap_or_else(|| unreachable!())
}
}
impl IdOrdItem for FdInfo {
type Key<'a> = &'a RawFd;
fn key(&self) -> &RawFd {
&self.fd
}
iddqd::id_upcast!();
}
#[derive(Copy)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum FdKind {
File,
Socket,
SockStream,
Poller,
Unknown,
}
impl FdKind {
pub fn name_str(self) -> &'static str {
use FdKind::*;
match self {
File => "file",
Socket => "socket",
SockStream => "socket stream",
Poller => "poller",
Unknown => "«unknown»",
}
}
}
impl Default for FdKind {
fn default() -> FdKind {
FdKind::Unknown
}
}
#[derive(Copy)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TokenFd {