Skip to content

Commit 96e864b

Browse files
authored
Merge pull request #4717 from RalfJung/epoll-level
epoll: make event delivery ready for level-triggered events
2 parents 0739f60 + 650b04b commit 96e864b

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

.github/workflows/setup/action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ runs:
2121
- name: Add cache for cargo
2222
id: cache
2323
uses: actions/cache@v4
24+
# FIXME: work around https://github.com/actions/runner-images/issues/13341
25+
if: runner.os != 'macOS'
2426
with:
2527
path: |
2628
# Taken from <https://doc.rust-lang.org/nightly/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci>.

src/shims/unix/linux_like/epoll.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::cell::RefCell;
22
use std::collections::{BTreeMap, BTreeSet, VecDeque};
33
use std::io;
4+
use std::ops::Bound;
45
use std::time::Duration;
56

67
use rustc_abi::FieldIdx;
@@ -611,8 +612,12 @@ fn return_ready_list<'tcx>(
611612
}
612613

613614
// While there is a slot to store another event, and an event to store, deliver that event.
615+
// We can't use an iterator over `ready_set` as we want to remove elements as we go,
616+
// so we track the most recently delivered event to find the next one. We track it as a lower
617+
// bound that we can pass to `BTreeSet::range`.
618+
let mut event_lower_bound = Bound::Unbounded;
614619
while let Some(slot) = array_iter.next(ecx)?
615-
&& let Some(&key) = ready_set.first()
620+
&& let Some(&key) = ready_set.range((event_lower_bound, Bound::Unbounded)).next()
616621
{
617622
let interest = interest_list.get_mut(&key).expect("non-existent event in ready set");
618623
// Deliver event to caller.
@@ -623,9 +628,10 @@ fn return_ready_list<'tcx>(
623628
num_of_events = num_of_events.strict_add(1);
624629
// Synchronize receiving thread with the event of interest.
625630
ecx.acquire_clock(&interest.clock)?;
626-
// Since currently, all events are edge-triggered, we remove them from the ready set when
627-
// they get delivered.
631+
// This was an edge-triggered event, so remove it from the ready set.
628632
ready_set.remove(&key);
633+
// Go find the next event.
634+
event_lower_bound = Bound::Excluded(key);
629635
}
630636
ecx.write_int(num_of_events, dest)?;
631637
interp_ok(num_of_events)

0 commit comments

Comments
 (0)