track poller and daemon fds like the rest
This commit is contained in:
parent
aee8dcb31a
commit
b11627d030
3 changed files with 271 additions and 82 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue