Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tokio::fs::read_dir loops infinitely on one entry #6096

Closed
Nughm3 opened this issue Oct 22, 2023 · 1 comment
Closed

tokio::fs::read_dir loops infinitely on one entry #6096

Nughm3 opened this issue Oct 22, 2023 · 1 comment
Labels
A-tokio Area: The main tokio crate C-bug Category: This is a bug. M-fs Module: tokio/fs

Comments

@Nughm3
Copy link

Nughm3 commented Oct 22, 2023

Version
tokio v1.33.0
rustc 1.75.0-nightly (249624b50 2023-10-20)

Platform
Linux nixos 6.5.8 #1-NixOS SMP PREEMPT_DYNAMIC Thu Oct 19 21:11:09 UTC 2023 x86_64 GNU/Linux

Description
When using tokio::fs::read_dir, it loops infinitely on one entry. These issues are similar: #5473, rust-lang/rust#50619

I tried this code:

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    for entry in std::fs::read_dir("dir")? {
        println!("std: {}", entry?.path().display());
    }

    while let Some(entry) = tokio::fs::read_dir("dir").await?.next_entry().await? {
        println!("tokio: {}", entry.path().display());
    }

    Ok(())
}

For the sake of the example both versions are in the same function, but I originally only had the tokio version, so I don't think that causes the problem.

The directory structure:

.
├── Cargo.lock
├── Cargo.toml
├── dir
│  ├── a
│  ├── b
│  └── c
└── src
   └── main.rs

I expected to see this happen:

std: dir/b
std: dir/c
std: dir/a
tokio: dir/b
tokio: dir/c
tokio: dir/a

(in some order)

Instead, this happened:

std: dir/b
std: dir/c
std: dir/a
tokio: dir/b
tokio: dir/b
tokio: dir/b
tokio: dir/b
tokio: dir/b
tokio: dir/b
tokio: dir/b
tokio: dir/b
...infinitely

It might be coincidental but in my original code (before reproducing the issue) it was also the 2nd entry alphabetically that was looping infinitely.

I've also tried using the ReadDirStream in tokio-stream and it yields the same result. It would be great to know if I'm misusing the API or if there is any way to fix this, thanks!

@Nughm3 Nughm3 added A-tokio Area: The main tokio crate C-bug Category: This is a bug. labels Oct 22, 2023
@satakuma
Copy link
Member

satakuma commented Oct 22, 2023

Since with every iteration of the loop you create a new ReadDir object (by calling tokio::fs::read_dir("dir")), you essentially start iterating from the beginning. You should create one ReadDir object and reuse it in the loop. The correct way to iterate over a directory should look like this:

let mut read_dir = tokio::fs::read_dir("dir").await?;
while let Some(entry) = read_dir.next_entry().await? {
    println!("tokio: {}", entry.path().display());
}

@satakuma satakuma closed this as not planned Won't fix, can't repro, duplicate, stale Oct 22, 2023
@satakuma satakuma added the M-fs Module: tokio/fs label Oct 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-bug Category: This is a bug. M-fs Module: tokio/fs
Projects
None yet
Development

No branches or pull requests

2 participants