-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
os: File.ReadDir is not concurrency safe on some platforms #66498
Comments
The docs of |
The docs don't mention concurrency safety, but (and someone who was around when the If (Of course, methods which modify file state are inherently unsafe-- |
On the other hand, we could special the |
In general, unless otherwise documented, standalone functions should be designed to be concurrency-safe, but methods of a type should not be assumed to be concurrency safe. So os.Open must be safe, but Read or ReadDir need not be. I don't think there's a bug or even a doc issue here. |
We do go to some trouble to ensure that concurrent calls to |
Concurrent calls to I think Should there be a version of |
I was coming here to file a similar issue, but found this first. My real-world use case is concurrent calls to
|
For the record: assuming you're using go1.22.0, this crash indicates a race on the File.dirInfo.buf buffer. |
There are races on https://github.com/golang/go/blob/go1.22.1/src/os/file_unix.go#L310-L313 func (file *file) close() error {
// ...
if file.dirinfo != nil {
file.dirinfo.close()
file.dirinfo = nil
}
// ...
} https://github.com/golang/go/blob/go1.22.1/src/os/dir_unix.go#L37-L42 func (d *dirInfo) close() {
if d.buf != nil {
dirBufPool.Put(d.buf)
d.buf = nil
}
} https://github.com/golang/go/blob/go1.22.1/src/os/dir_unix.go#L46-L50 func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
if f.dirinfo == nil {
f.dirinfo = new(dirInfo)
f.dirinfo.buf = dirBufPool.Get().(*[]byte)
}
d := f.dirinfo
// ... many uses of d.buf ...
} |
Leaning towards
Cf. https://go.dev/doc/comment#type [2024-04-04]
Cf. https://go.dev/doc/comment#func [2024-04-04] |
It might not hurt to make an exception to the rule here and redundantly document the lack of concurrency safety, because many readers may wrongly assume that Read, Write, ReadDir, and other methods named for UNIX system calls are nothing more than wrappers around those system calls. |
Concurrency is built into
Cf. https://pkg.go.dev/io@go1.22.2#ReaderAt [2024-04-04] |
The documentation for the |
Change https://go.dev/cl/578322 mentions this issue: |
Note: the subject of the fix as merged was "os: make File.Readdir et al concurrency-safe". |
The Unix implementation of
File.readdir
accesses an internal buffer without synchronization. SimultaneousReadDir
calls on the same*os.File
will race and misbehave.The text was updated successfully, but these errors were encountered: