Eugene-Usachev
@Eugene-Usachev

Почему в этом коде значение под указателем перезаписывается?

Я пытаюсь разобраться с 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)
  • Вопрос задан
  • 102 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы