11use std:: cell:: RefCell ;
22use std:: collections:: { BTreeMap , BTreeSet , VecDeque } ;
33use std:: io;
4+ use std:: ops:: Bound ;
45use std:: time:: Duration ;
56
67use 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