@@ -79,12 +79,13 @@ where
7979 ///
8080 /// If the closure is called *before* the event is processed:
8181 /// - The third argument will be `None`
82- /// - The event is still present in the network's queue
82+ /// - The event is still present in the network's queue (and therefore unfiltered)
8383 ///
8484 /// If the closure is called *after* the event is processed:
8585 /// - The third argument will contain a `Some((StepUpdate, Vec<Event>))` tuple, where the second element
8686 /// contains a list of events that were generated by the event that was just processed.
8787 /// - These events have not been enqueued yet
88+ /// - The second argument will be the popped (filtered) event
8889 fn simulate_hooked (
8990 & mut self ,
9091 f : impl FnMut (
@@ -263,7 +264,7 @@ impl<P: Prefix, Q: EventQueue<P>, Ospf: OspfImpl> InteractiveNetwork<P, Q, Ospf>
263264 let mut remaining_iter = self . stop_after ;
264265 ' timeout: loop {
265266 // While there are events in the queue
266- while let Some ( event) = self . queue ( ) . peek ( ) {
267+ ' queue : while let Some ( event) = self . queue ( ) . peek ( ) {
267268 // Ensure the convergence limit is not overstepped
268269 if let Some ( rem) = remaining_iter {
269270 if rem == 0 {
@@ -276,18 +277,20 @@ impl<P: Prefix, Q: EventQueue<P>, Ospf: OspfImpl> InteractiveNetwork<P, Q, Ospf>
276277 // Straddle the trigger_event function with the pre- and post-event hooks
277278 f ( self , event, None ) ;
278279 // Safety: This is safe because we trigger the next event in the queue and
279- // we still push all resulting events to the queue. The extracted events are
280- // all immutable and won't be modified.
281- // Since the closure's reference to the network is immutable as well, this unwrap
282- // is always safe
283- let event = self . queue_mut ( ) . pop ( ) . unwrap ( ) ;
284- let event_clone = event. clone ( ) ;
285- let result = unsafe { self . trigger_event ( event) ? } ;
286- f ( self , & event_clone, Some ( & result) ) ;
280+ // we still push all resulting events to the queue. The extracted events as well as the
281+ // reference to the network are all immutable in this closure and won't be modified.
282+ //
283+ // The check below however is still needed, because `EventQueue::peek()` is allowed
284+ // to return an event that is actually not returned by `EventQueue::pop()`
285+ let Some ( popped_event) = self . queue_mut ( ) . pop ( ) else {
286+ break ' queue;
287+ } ;
288+ let result = unsafe { self . trigger_event ( popped_event. clone ( ) ) ? } ;
289+ f ( self , & popped_event, Some ( & result) ) ;
287290
288291 self . enqueue_events ( result. 1 ) ;
289292
290- if matches ! ( event_clone , Event :: Ospf { .. } ) {
293+ if matches ! ( popped_event , Event :: Ospf { .. } ) {
291294 // OSPF event received! Check the BGP session state
292295 self . refresh_bgp_sessions ( ) ?;
293296 }
0 commit comments