Skip to content

measure_many hangs with current_thread tokio runtime #1

@ThinkerDreamer

Description

@ThinkerDreamer

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 message is in the channel
  • Background task is blocked on socket recv
  • Reply arrives before Subscribe is processed
  • Reply gets dropped

Suggested fix: Use tokio::select! to wait on both the subscription channel and socket recv simultaneously. Edit: This was not a feasible solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions