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

Send not implemented for std::fs::read_dir #22577

Closed
markuskobler opened this issue Feb 20, 2015 · 3 comments · Fixed by #22594
Closed

Send not implemented for std::fs::read_dir #22577

markuskobler opened this issue Feb 20, 2015 · 3 comments · Fixed by #22594

Comments

@markuskobler
Copy link

Now that the new std::fs changes #21936 have landed. I'm getting the following error with code similar to this snippet http://is.gd/6usayc

fn scan_dir(dir: &Path, pool: &TaskPool, tx: Sender<Vec<io::Result<()>>>) -> io::Result<()> {
    // Read directory outside of task pool
    let entries = try!(fs::read_dir(dir));
    pool.execute(move || {
        let mut stats = Vec::new();
        for entry in entries {
            /* ...process files... */
        }
        tx.send(stats).unwrap();
    });
    Ok(())
}

Error:

<anon>:27:10: 33:7 error: the trait `core::marker::Send` is not implemented for the type `*mut libc::types::common::posix88::DIR` [E0277]
          ...
<anon>:27:10: 33:7 note: `*mut libc::types::common::posix88::DIR` cannot be sent between threads safely

Is it really unsafe to move the read_dir results to a TaskPool?

@nagisa
Copy link
Member

nagisa commented Feb 20, 2015

Note that the function does not build a list, but rather generates results lazily, therefore yes, sending result of fs::read_dir into a thread is not safe.

Wrap the iterator into Arc<Mutex<>> or build a list before sending it to the thread pool with fs::read_dir(dir).collect<Vec<_>>().

@markuskobler
Copy link
Author

Thanks @nagisa that allows me to work around the issue but looking at the code its not clear, to me at least, what benefit of an Rc is in https://github.com/rust-lang/rust/blob/master/src/libstd/sys/unix/fs2.rs.

pub struct ReadDir {
    dirp: *mut libc::DIR,
    root: Rc<PathBuf>,
}

pub struct DirEntry {
    buf: Vec<u8>,
    dirent: *mut libc::dirent_t,
    root: Rc<PathBuf>,
}

@nagisa
Copy link
Member

nagisa commented Feb 20, 2015

Rc only allows sharing a pointer inside the same thread. I can’t quite say now why Rc is necessary here without looking at the code, but it is an implementation detail and doesn’t help to deal with the original problem.

alexcrichton added a commit to alexcrichton/rust that referenced this issue Feb 20, 2015
The windows/unix modules were currently inconsistent about the traits being
implemented for `DirEntry` and there isn't much particular reason why the traits
*couldn't* be implemented for `ReadDir` and `DirEntry`, so this commit ensures
that they are implemented.

Closes rust-lang#22577
Manishearth added a commit to Manishearth/rust that referenced this issue Feb 24, 2015
 The windows/unix modules were currently inconsistent about the traits being
implemented for `DirEntry` and there isn't much particular reason why the traits
*couldn't* be implemented for `ReadDir` and `DirEntry`, so this commit ensures
that they are implemented.

Closes rust-lang#22577
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants