Skip to content

Commit

Permalink
Fixed formatting, reduced the scope of the unsafe call to `trigger_ev…
Browse files Browse the repository at this point in the history
…ent`, added satefy notice to the unsafe call
  • Loading branch information
Pietroro committed Jan 14, 2025
1 parent da13d55 commit 03ca65a
Showing 1 changed file with 46 additions and 38 deletions.
84 changes: 46 additions & 38 deletions bgpsim/src/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,25 @@ where
/// be set by `self.set_msg_limit`).
fn simulate(&mut self) -> Result<(), NetworkError>;

/// Similarly to the [`Network::simulate`] function, this function will execute all events in the
/// queue. This function provides a hook in the form of a closure that is called before and after
/// Similarly to the [`Network::simulate`] function, this function will execute all events in the
/// queue. This function provides a hook in the form of a closure that is called before and after
/// each event is processed.
///
/// The closure always provides immutable access to both the network and the currently processed
/// event. Furthermore, it enables the user to determine whether it was called before or after
///
/// The closure always provides immutable access to both the network and the currently processed
/// event. Furthermore, it enables the user to determine whether it was called before or after
/// the event was processed based on the value of the third argument.
///
///
/// If the closure is called *before* the event is processed, the third argument will be `None`.
/// If the closure is called *after* the event is processed, the third argument will contain a
/// `Some((StepUpdate, Vec<Event>))` tuple, where the second element contains a list of events
/// that were generated by the event that was just processed.
fn simulate_hooked(
net: &mut Network<P, Q, Ospf>,
f: impl FnMut(&Network<P, Q, Ospf>, &Event<P, Q::Priority>, Option<&(StepUpdate<P>, Vec<Event<P, Q::Priority>>)>) -> (),
f: impl FnMut(
&Network<P, Q, Ospf>,
&Event<P, Q::Priority>,
Option<&(StepUpdate<P>, Vec<Event<P, Q::Priority>>)>,
) -> (),

Check failure on line 86 in bgpsim/src/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded unit return type
) -> Result<(), NetworkError>;

/// Trigger the timeout event on any router. The router is picked randomly if the feature `rand`
Expand Down Expand Up @@ -228,44 +232,48 @@ impl<P: Prefix, Q: EventQueue<P>, Ospf: OspfImpl> InteractiveNetwork<P, Q, Ospf>
}

fn simulate_hooked(
net: &mut Network<P, Q, Ospf>,
mut f: impl FnMut(&Network<P, Q, Ospf>, &Event<P, Q::Priority>, Option<&(StepUpdate<P>, Vec<Event<P, Q::Priority>>)>) -> (),
) -> Result<(), NetworkError>
{
'timeout: loop {
// While there are events in the queue
while let Some(event) = net.queue_mut().pop() {
let event_clone = event.clone();

unsafe {
// Straddle the trigger_event function with the pre- and post-event hooks
f(net, &event_clone, None);
let result = net.trigger_event(event)?;
f(net, &event_clone, Some(&result));

net.enqueue_events(result.1);
}
net: &mut Network<P, Q, Ospf>,
mut f: impl FnMut(
&Network<P, Q, Ospf>,
&Event<P, Q::Priority>,
Option<&(StepUpdate<P>, Vec<Event<P, Q::Priority>>)>,
) -> (),

Check failure on line 240 in bgpsim/src/interactive.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded unit return type
) -> Result<(), NetworkError> {
'timeout: loop {
// While there are events in the queue
while let Some(event) = net.queue_mut().pop() {
let event_clone = event.clone();

if matches!(event_clone, Event::Ospf { .. }) {
// OSPF event received! Check the BGP session state
net.refresh_bgp_sessions()?;
}
}
// Straddle the trigger_event function with the pre- and post-event hooks
f(net, &event_clone, None);
// Safety: This is safe because we are allowing the network to eventually
// converge by exhausing all events in the queue. The extracted events are
// all immutable and won't be modified.
let result = unsafe { net.trigger_event(event)? };
f(net, &event_clone, Some(&result));

// trigger the next timeout event if it exists.
let trigger_router = net.trigger_timeout()?;
net.enqueue_events(result.1);

// if no timeout was triggered, break out of the loop. We are converged!
if trigger_router.is_none() {
break 'timeout;
if matches!(event_clone, Event::Ospf { .. }) {
// OSPF event received! Check the BGP session state
net.refresh_bgp_sessions()?;
}
}

// remove unreachable OSPF LSAs
net.internal_routers_mut()
.for_each(|r| r.ospf.remove_unreachable_lsas());
// trigger the next timeout event if it exists.
let trigger_router = net.trigger_timeout()?;

// if no timeout was triggered, break out of the loop. We are converged!
if trigger_router.is_none() {
break 'timeout;
}
}

// remove unreachable OSPF LSAs
net.internal_routers_mut()
.for_each(|r| r.ospf.remove_unreachable_lsas());

Ok(())
Ok(())
}

fn trigger_timeout(&mut self) -> Result<Option<RouterId>, NetworkError> {
Expand Down

0 comments on commit 03ca65a

Please sign in to comment.