mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 18:03:25 +00:00
Avoid nested loops
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
25daab7e78
commit
d70ae181b5
@ -212,55 +212,46 @@ impl EpollFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pop_ready(&self, max_events: usize, ep_events: &mut Vec<EpollEvent>) -> usize {
|
fn pop_ready(&self, max_events: usize, ep_events: &mut Vec<EpollEvent>) -> usize {
|
||||||
let mut count_events = 0;
|
|
||||||
let mut ready = self.ready.lock();
|
let mut ready = self.ready.lock();
|
||||||
let mut pop_quota = ready.len();
|
|
||||||
loop {
|
let mut count_events = 0;
|
||||||
// Pop some ready entries per round.
|
for _ in 0..ready.len() {
|
||||||
//
|
if count_events >= max_events {
|
||||||
// Since the popped ready entries may contain "false positive" and
|
|
||||||
// we want to return as many results as possible, this has to
|
|
||||||
// be done in a loop.
|
|
||||||
let pop_count = (max_events - count_events).min(pop_quota);
|
|
||||||
if pop_count == 0 {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let ready_entries: Vec<Arc<EpollEntry>> = ready
|
|
||||||
.drain(..pop_count)
|
|
||||||
.filter_map(|entry| Weak::upgrade(&entry))
|
|
||||||
.collect();
|
|
||||||
pop_quota -= pop_count;
|
|
||||||
|
|
||||||
// Examine these ready entries, which are candidates for the results
|
let weak_entry = ready.pop_front().unwrap();
|
||||||
// to be returned.
|
let Some(entry) = Weak::upgrade(&weak_entry) else {
|
||||||
for entry in ready_entries {
|
// The entry has been deleted.
|
||||||
let (ep_event, ep_flags) = entry.event_and_flags();
|
continue;
|
||||||
// If this entry's file is ready, save it in the output array.
|
};
|
||||||
// EPOLLHUP and EPOLLERR should always be reported.
|
|
||||||
let ready_events = entry.poll() & (ep_event.events | IoEvents::HUP | IoEvents::ERR);
|
|
||||||
|
|
||||||
// Records the events from the ready list
|
let (ep_event, ep_flags) = entry.event_and_flags();
|
||||||
if !ready_events.is_empty() {
|
// If this entry's file is ready, save it in the output array.
|
||||||
ep_events.push(EpollEvent::new(ready_events, ep_event.user_data));
|
// EPOLLHUP and EPOLLERR should always be reported.
|
||||||
count_events += 1;
|
let ready_events = entry.poll() & (ep_event.events | IoEvents::HUP | IoEvents::ERR);
|
||||||
}
|
|
||||||
|
|
||||||
// If there are events and the epoll entry is neither edge-triggered
|
// Records the events from the ready list
|
||||||
// nor one-shot, then we should keep the entry in the ready list.
|
if !ready_events.is_empty() {
|
||||||
if !ready_events.is_empty()
|
ep_events.push(EpollEvent::new(ready_events, ep_event.user_data));
|
||||||
&& !ep_flags.intersects(EpollFlags::ONE_SHOT | EpollFlags::EDGE_TRIGGER)
|
count_events += 1;
|
||||||
{
|
}
|
||||||
ready.push_back(Arc::downgrade(&entry));
|
|
||||||
}
|
// If there are events and the epoll entry is neither edge-triggered
|
||||||
// Otherwise, the entry is indeed removed the ready list and we should reset
|
// nor one-shot, then we should keep the entry in the ready list.
|
||||||
// its ready flag.
|
if !ready_events.is_empty()
|
||||||
else {
|
&& !ep_flags.intersects(EpollFlags::ONE_SHOT | EpollFlags::EDGE_TRIGGER)
|
||||||
entry.reset_ready();
|
{
|
||||||
// For EPOLLONESHOT flag, this entry should also be removed from the interest list
|
ready.push_back(weak_entry);
|
||||||
if ep_flags.intersects(EpollFlags::ONE_SHOT) {
|
}
|
||||||
self.del_interest(entry.fd())
|
// Otherwise, the entry is indeed removed the ready list and we should reset
|
||||||
.expect("this entry should be in the interest list");
|
// its ready flag.
|
||||||
}
|
else {
|
||||||
|
entry.reset_ready();
|
||||||
|
// For EPOLLONESHOT flag, this entry should also be removed from the interest list
|
||||||
|
if ep_flags.intersects(EpollFlags::ONE_SHOT) {
|
||||||
|
self.del_interest(entry.fd())
|
||||||
|
.expect("this entry should be in the interest list");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,6 +260,7 @@ impl EpollFile {
|
|||||||
if ready.len() == 0 {
|
if ready.len() == 0 {
|
||||||
self.pollee.del_events(IoEvents::IN);
|
self.pollee.del_events(IoEvents::IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
count_events
|
count_events
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user