diff --git a/kernel/src/fs/epoll/epoll_file.rs b/kernel/src/fs/epoll/epoll_file.rs index 84e2d7c67..e9f21bdc2 100644 --- a/kernel/src/fs/epoll/epoll_file.rs +++ b/kernel/src/fs/epoll/epoll_file.rs @@ -104,7 +104,7 @@ impl EpollFile { } let entry = EpollEntry::new(fd, Arc::downgrade(&file).into(), self.weak_self.clone()); - let events = entry.update(ep_event, ep_flags)?; + let events = entry.update(ep_event, ep_flags); let ready_entry = if !events.is_empty() { Some(entry.clone()) @@ -165,7 +165,7 @@ impl EpollFile { .ok_or_else(|| { Error::with_message(Errno::ENOENT, "the file is not in the interest list") })?; - let events = entry.update(new_ep_event, new_ep_flags)?; + let events = entry.update(new_ep_event, new_ep_flags); if !events.is_empty() { Some(entry.clone()) @@ -416,18 +416,7 @@ impl From<(FileDesc, &Arc)> for EpollEntryKey { struct EpollEntryInner { event: EpollEvent, flags: EpollFlags, -} - -impl Default for EpollEntryInner { - fn default() -> Self { - Self { - event: EpollEvent { - events: IoEvents::empty(), - user_data: 0, - }, - flags: EpollFlags::empty(), - } - } + poller: PollHandle, } impl EpollEntry { @@ -437,13 +426,24 @@ impl EpollEntry { file: KeyableWeak, weak_epoll: Weak, ) -> Arc { - Arc::new_cyclic(|me| Self { - key: EpollEntryKey { fd, file }, - inner: Mutex::new(EpollEntryInner::default()), - is_enabled: AtomicBool::new(false), - is_ready: AtomicBool::new(false), - weak_epoll, - weak_self: me.clone(), + Arc::new_cyclic(|me| { + let inner = EpollEntryInner { + event: EpollEvent { + events: IoEvents::empty(), + user_data: 0, + }, + flags: EpollFlags::empty(), + poller: PollHandle::new(me.clone() as _), + }; + + Self { + key: EpollEntryKey { fd, file }, + inner: Mutex::new(inner), + is_enabled: AtomicBool::new(false), + is_ready: AtomicBool::new(false), + weak_epoll, + weak_self: me.clone(), + } }) } @@ -457,11 +457,6 @@ impl EpollEntry { self.weak_self.upgrade().unwrap() } - /// Get an instance of `Weak` that refers to this epoll entry. - pub fn self_weak(&self) -> Weak { - self.weak_self.clone() - } - /// Get the file associated with this epoll entry. /// /// Since an epoll entry only holds a weak reference to the file, @@ -513,30 +508,27 @@ impl EpollEntry { /// Updates the epoll entry by the given event masks and flags. /// /// This method needs to be called in response to `EpollCtl::Add` and `EpollCtl::Mod`. - pub fn update(&self, event: EpollEvent, flags: EpollFlags) -> Result { + pub fn update(&self, event: EpollEvent, flags: EpollFlags) -> IoEvents { let file = self.file().unwrap(); let mut inner = self.inner.lock(); - file.register_observer(self.self_weak(), event.events)?; - *inner = EpollEntryInner { event, flags }; + inner.event = event; + inner.flags = flags; self.set_enabled(&inner); - let events = file.poll(event.events, None); - Ok(events) + file.poll(event.events, Some(&mut inner.poller)) } /// Shuts down the epoll entry. /// /// This method needs to be called in response to `EpollCtl::Del`. pub fn shutdown(&self) { - let inner = self.inner.lock(); + let mut inner = self.inner.lock(); - if let Some(file) = self.file() { - file.unregister_observer(&(self.self_weak() as _)).unwrap(); - }; self.reset_enabled(&inner); + inner.poller.reset(); } /// Returns whether the epoll entry is in the ready list.