Skip to content

Commit

Permalink
Refactor the logic
Browse files Browse the repository at this point in the history
  • Loading branch information
tiif committed Aug 17, 2024
1 parent a9eb9d9 commit 6431733
Showing 1 changed file with 31 additions and 24 deletions.
55 changes: 31 additions & 24 deletions src/shims/unix/linux/epoll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,35 +431,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let mut num_of_events: i32 = 0;
let mut array_iter = this.project_array_fields(&event)?;

while let Some(des) = array_iter.next(this)?
&& !ready_list.is_empty()
{
let mut entry_written = false;
// Fetch an event from the ready list.
while !entry_written {
if let Some((epoll_key, epoll_return)) = ready_list.pop_first() {
// If the file description is fully close, the entry for corresponding FdID in the
// global epoll event interest table would be empty.
if this.machine.epoll_interests.get_epoll_interest(epoll_key.0).is_some() {
// Return notification to the caller if the file description is not fully closed.
this.write_int_fields_named(
&[
("events", epoll_return.events.into()),
("u64", epoll_return.data.into()),
],
&des.1,
)?;
num_of_events = num_of_events.checked_add(1).unwrap();
entry_written = true;
}
} else {
break;
}
while let Some(des) = array_iter.next(this)? {
if let Some(epoll_event_instance) = this.ready_list_next(&mut ready_list) {
this.write_int_fields_named(
&[
("events", epoll_event_instance.events.into()),
("u64", epoll_event_instance.data.into()),
],
&des.1,
)?;
num_of_events = num_of_events.checked_add(1).unwrap();
} else {
break;
}
}
Ok(Scalar::from_i32(num_of_events))
}

/// This function takes in ready list and returns EpollEventInstance with file descriptions
/// that are not closed.
fn ready_list_next(
&self,
ready_list: &mut BTreeMap<(FdId, i32), EpollEventInstance>,
) -> Option<EpollEventInstance> {
let this = self.eval_context_ref();
while let Some((epoll_key, epoll_event_instance)) = ready_list.pop_first() {
// This ensures that we only return events that we are interested. The FD might have been closed since
// the event was generated, in which case we are not interested anymore.
if this.machine.epoll_interests.get_epoll_interest(epoll_key.0).is_some() {
// If the file description is fully close, the entry for corresponding FdID in the
// global epoll event interest table would be empty.
return Some(epoll_event_instance);
}
}
return None;
}

/// For a specific file description, get its ready events and update the corresponding ready
/// list. This function should be called whenever an event causes more bytes or an EOF to become
/// newly readable from an FD, and whenever more bytes can be written to an FD or no more future
Expand Down

0 comments on commit 6431733

Please sign in to comment.