-
Notifications
You must be signed in to change notification settings - Fork 2
Closed
Description
MeasureManyStream::next() never returns when using tokio's current_thread runtime, even when pinging localhost.
Reproduction:
use std::{net::IpAddr, time::Duration};
use futures_util::StreamExt;
use massping::DualstackPinger;
#[tokio::main(flavor = "current_thread")]
async fn main() {
let localhost: IpAddr = "127.0.0.1".parse().unwrap();
let pinger = DualstackPinger::new().unwrap();
let mut stream = pinger.measure_many([localhost].into_iter());
// This hangs forever
stream.next().await;
}Works with multi_thread runtime, hangs with current_thread.
Possible cause: In pinger.rs, the background receive task uses try_recv() to process subscriptions, then blocks on recv().await. With a single-threaded runtime, when a new subscription is sent after the task is already blocking on recv(), it never gets processed - the ICMP reply arrives but gets dropped because the subscriber isn't registered yet.
It appears to be a race condition:
Subscribe messageis in the channel- Background task is blocked on socket recv
- Reply arrives before
Subscribeis processed - Reply gets dropped
Suggested fix: Use Edit: This was not a feasible solution.tokio::select! to wait on both the subscription channel and socket recv simultaneously.
Metadata
Metadata
Assignees
Labels
No labels