tokio-rs / tokio

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
https://tokio.rs
MIT License
25.71k stars 2.35k forks source link

tokio::sync::mpsc::bounded::Receiver<T>::is_empty() returns false when recv().await blocks #6594

Closed saltatory closed 1 month ago

saltatory commented 1 month ago

Version

└── tokio v1.37.0
    ├── num_cpus v1.16.0
    │   └── libc v0.2.154
    ├── pin-project-lite v0.2.14
    └── tokio-macros v2.2.0 (proc-macro)
        ├── proc-macro2 v1.0.82 (*)
        ├── quote v1.0.36 (*)
        └── syn v2.0.63 (*)

Platform

Linux Seiza 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Issue

TL;DR: tokio:::sync::mpsc::bounded::Receiver<T>::is_empty() returns false but when immediately followed by tokio::sync::mpsc::bounded::Receiver<T>::recv() the recv()blocks.

I have a message-oriented IO library that is communicating with io-uring. Before I attempt to recv() IO messages on my channel, I check that both io-uring submission queue is not full and that Receiver is not empty before calling recv().await. The is_empty() call returns false but the recv() blocks.

saltatory commented 1 month ago

Quick update: the same logic refactored to use try_recv() works fine.

Darksonn commented 1 month ago

Can you please provide more information? We have a fair number of tests on this:

https://github.com/tokio-rs/tokio/blob/9e00b266e08d263c497dc9de57d9acbc049ae69b/tokio/tests/sync_mpsc.rs#L1092-L1151

If you're able to provide an example that displays the bug, then that would be very helpful.

Darksonn commented 1 month ago

Closing as duplicate of #6602. Thank you for reporting this bug.