Я пытаюсь разобраться с epoll. У меня есть некий EventData
pub struct EventData {
pub fd: RawFd,
}
И есть некий selector, который имеет методы add_fd и select.
#[inline(always)]
pub fn select(&self, events: &mut [EpollEvent], wait: Option<u64>) -> io::Result<Option<u64>> {
let timeout_ms = wait
.map(|to| EpollTimeout::try_from(ns_to_ms(to)).unwrap())
.unwrap_or(EpollTimeout::NONE);
let n = self.selector.epoll.wait(events, timeout_ms)?;
for event in unsafe { events.get_unchecked_mut(..n) } {
if event.data() == 0 {
// this is just a wakeup event, ignore it
let mut buf = [0u8; 8];
// clear the event_fd, ignore the result
read(self.selector.event_fd.as_raw_fd(), &mut buf).ok();
continue;
}
let data = unsafe { ptr::read(event.data() as *mut ManuallyDrop<EventData>) };
println!("event: {}", data.fd);
}
if n == 0 {
// zero events, so we can sleep
Ok(None)
} else if n < 64{
Ok(Some(1_000_000))
} else {
// n >= 64, so we can call epoll again immediately, because it has enough events
Ok(Some(0))
}
}
#[inline(always)]
pub fn add_fd(&self, fd: RawFd) -> nix::Result<()> {
let data = new_event_data(fd, None);
let md = ManuallyDrop::new(data);
let info = EpollEvent::new(
EpollFlags::EPOLLIN
| EpollFlags::EPOLLOUT
| EpollFlags::EPOLLRDHUP
| EpollFlags::EPOLLET,
&md as *const _ as u64,
);
self.selector.epoll.add(unsafe { BorrowedFd::borrow_raw(fd) }, info)
}
Я ожидаю, что получу свой EventData в select и уже там его очищу. Проблема в том, что я получаю не то значение fd, которое кладу.
EventData никогда не очищается и никогда не перезаписывается (select вызывается строго последовательно). Почему я не получаю свой fd? (в этом коде используется библиотека nix)