From f3fcaf776c8dae48f8c257047d9ea4fce4276795 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 14 Mar 2023 13:11:59 +0100 Subject: [PATCH] iomanager: Collect all sources with zero timeouts as ready Previously, if two iosources returned 0.0 as their timeout, only one of them would be considered ready. An always ready source therefore may starve other ready ones due to this and minimally this behavior seems surprising. Offline pcap sources are always ready and return 0.0 for GetNextTimeout() (unless in pseudo-realtime), so we can also remove the offline source special case. One subtle side-effect of this change is that if an IO source returns a 0.0 timeout *and* it's file descriptor is ready in the same loop iteration, it may be processed twice. --- src/iosource/Manager.cc | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/iosource/Manager.cc b/src/iosource/Manager.cc index 61e6b5df07..da2f790cb8 100644 --- a/src/iosource/Manager.cc +++ b/src/iosource/Manager.cc @@ -157,25 +157,24 @@ void Manager::FindReadySources(ReadySources* ready) if ( iosource->IsOpen() ) { double next = iosource->GetNextTimeout(); - bool added = false; if ( timeout == -1 || (next >= 0.0 && next < timeout) ) { timeout = next; timeout_src = iosource; - - // If a source has a zero timeout then it's ready. Just add it to the - // list already. Only do this if it's not time to poll though, since - // we don't want things in the vector passed into Poll() or it'll end - // up inserting duplicates. - if ( timeout == 0 && ! time_to_poll ) - { - added = true; - ready->push_back({timeout_src, -1, 0}); - } } - if ( iosource == pkt_src && ! added ) + // If a source has a zero timeout then it's ready. Just add it to the + // list already. Only do this if it's not time to poll though, since + // we don't want things in the vector passed into Poll() or it'll end + // up inserting duplicates. A source with a zero timeout that was not + // selected as the timeout_src can be safely added, whether it's time + // to poll or not though. + if ( next == 0 && (! time_to_poll || iosource != timeout_src) ) + { + ready->push_back({iosource, -1, 0}); + } + else if ( iosource == pkt_src ) { if ( pkt_src->IsLive() ) { @@ -185,12 +184,6 @@ void Manager::FindReadySources(ReadySources* ready) // Poll() and end up dropping packets. ready->push_back({pkt_src, -1, 0}); } - else - { - if ( ! run_state::pseudo_realtime && ! time_to_poll ) - // A pcap file is always ready to process unless it's suspended - ready->push_back({pkt_src, -1, 0}); - } } } }