Use PollAdaptor in EpollFile

This commit is contained in:
Ruihan Li
2024-09-01 22:12:34 +08:00
committed by Tate, Hongliang Tian
parent e32fb2f91b
commit 27ae4cb9e7

View File

@ -104,7 +104,7 @@ impl EpollFile {
} }
let entry = EpollEntry::new(fd, Arc::downgrade(&file).into(), self.weak_self.clone()); 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() { let ready_entry = if !events.is_empty() {
Some(entry.clone()) Some(entry.clone())
@ -165,7 +165,7 @@ impl EpollFile {
.ok_or_else(|| { .ok_or_else(|| {
Error::with_message(Errno::ENOENT, "the file is not in the interest list") 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() { if !events.is_empty() {
Some(entry.clone()) Some(entry.clone())
@ -416,18 +416,7 @@ impl From<(FileDesc, &Arc<dyn FileLike>)> for EpollEntryKey {
struct EpollEntryInner { struct EpollEntryInner {
event: EpollEvent, event: EpollEvent,
flags: EpollFlags, flags: EpollFlags,
} poller: PollHandle,
impl Default for EpollEntryInner {
fn default() -> Self {
Self {
event: EpollEvent {
events: IoEvents::empty(),
user_data: 0,
},
flags: EpollFlags::empty(),
}
}
} }
impl EpollEntry { impl EpollEntry {
@ -437,13 +426,24 @@ impl EpollEntry {
file: KeyableWeak<dyn FileLike>, file: KeyableWeak<dyn FileLike>,
weak_epoll: Weak<EpollFile>, weak_epoll: Weak<EpollFile>,
) -> Arc<Self> { ) -> Arc<Self> {
Arc::new_cyclic(|me| Self { Arc::new_cyclic(|me| {
key: EpollEntryKey { fd, file }, let inner = EpollEntryInner {
inner: Mutex::new(EpollEntryInner::default()), event: EpollEvent {
is_enabled: AtomicBool::new(false), events: IoEvents::empty(),
is_ready: AtomicBool::new(false), user_data: 0,
weak_epoll, },
weak_self: me.clone(), 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() self.weak_self.upgrade().unwrap()
} }
/// Get an instance of `Weak` that refers to this epoll entry.
pub fn self_weak(&self) -> Weak<Self> {
self.weak_self.clone()
}
/// Get the file associated with this epoll entry. /// Get the file associated with this epoll entry.
/// ///
/// Since an epoll entry only holds a weak reference to the file, /// 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. /// 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`. /// This method needs to be called in response to `EpollCtl::Add` and `EpollCtl::Mod`.
pub fn update(&self, event: EpollEvent, flags: EpollFlags) -> Result<IoEvents> { pub fn update(&self, event: EpollEvent, flags: EpollFlags) -> IoEvents {
let file = self.file().unwrap(); let file = self.file().unwrap();
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
file.register_observer(self.self_weak(), event.events)?; inner.event = event;
*inner = EpollEntryInner { event, flags }; inner.flags = flags;
self.set_enabled(&inner); 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. /// Shuts down the epoll entry.
/// ///
/// This method needs to be called in response to `EpollCtl::Del`. /// This method needs to be called in response to `EpollCtl::Del`.
pub fn shutdown(&self) { 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); self.reset_enabled(&inner);
inner.poller.reset();
} }
/// Returns whether the epoll entry is in the ready list. /// Returns whether the epoll entry is in the ready list.