-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: document concurrency properties for File methods #56043
Comments
Unless we're willing to put locks everywhere, I'm not sure what we can say beyond saying to read the documents for the operating system. |
Change https://go.dev/cl/438347 mentions this issue: |
As it happens, we actually already have all the required locks for regular files or pipes, on all systems other than Plan 9. I've already sent CL 438347 to fix Plan 9. We have the locks because we need them anyhow for the runtime poller. The current exception is for directories. For directories os files have a |
Change https://go.dev/cl/439195 mentions this issue: |
Change https://go.dev/cl/439595 mentions this issue: |
This permits us to safely support concurrent access to files on Plan 9. Concurrent access was already safe on other systems. This does introduce a change: if one goroutine calls a blocking read on a pipe, and another goroutine closes the pipe, then before this CL the close would occur. Now the close will be delayed until the blocking read completes. Also add tests that concurrent I/O and Close on a pipe are OK. For #50436 For #56043 Change-Id: I969c869ea3b8c5c2f2ef319e441a56a3c64e7bf5 Reviewed-on: https://go-review.googlesource.com/c/go/+/438347 Reviewed-by: Bryan Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: David du Colombier <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Rob Pike <[email protected]>
As of CL 438347, multiple concurrents calls to Close should be safe. This removes some indirection and may also make some programs that use type-assertions marginally more efficient. For example, if a program calls (*exec.Cmd).StdinPipe to obtain a pipe and then sets that as the Stdout of another command, that program will now allow the second command to inherit the file descriptor directly instead of copying everything through a goroutine. This will also cause calls to Close after the first to return an error wrapping os.ErrClosed instead of nil. However, it seems unlikely that programs will depend on that error behavior: if a program is calling Write in a loop followed by Close, then if a racing Close occurs it is likely that the Write would have already reported an error. (The only programs likely to notice a change are those that call Close — without Write! — after a call to Wait.) Updates #56043. Updates #9307. Updates #6270. Change-Id: Iec734b23acefcc7e7ad0c8bc720085bc45988efb Reviewed-on: https://go-review.googlesource.com/c/go/+/439195 Reviewed-by: Ian Lance Taylor <[email protected]> Auto-Submit: Bryan Mills <[email protected]> Run-TryBot: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
This permits us to safely support concurrent access to files on Plan 9. Concurrent access was already safe on other systems. This does introduce a change: if one goroutine calls a blocking read on a pipe, and another goroutine closes the pipe, then before this CL the close would occur. Now the close will be delayed until the blocking read completes. Also add tests that concurrent I/O and Close on a pipe are OK. For golang#50436 For golang#56043 Change-Id: I969c869ea3b8c5c2f2ef319e441a56a3c64e7bf5 Reviewed-on: https://go-review.googlesource.com/c/go/+/438347 Reviewed-by: Bryan Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: David du Colombier <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Rob Pike <[email protected]>
As of CL 438347, multiple concurrents calls to Close should be safe. This removes some indirection and may also make some programs that use type-assertions marginally more efficient. For example, if a program calls (*exec.Cmd).StdinPipe to obtain a pipe and then sets that as the Stdout of another command, that program will now allow the second command to inherit the file descriptor directly instead of copying everything through a goroutine. This will also cause calls to Close after the first to return an error wrapping os.ErrClosed instead of nil. However, it seems unlikely that programs will depend on that error behavior: if a program is calling Write in a loop followed by Close, then if a racing Close occurs it is likely that the Write would have already reported an error. (The only programs likely to notice a change are those that call Close — without Write! — after a call to Wait.) Updates golang#56043. Updates golang#9307. Updates golang#6270. Change-Id: Iec734b23acefcc7e7ad0c8bc720085bc45988efb Reviewed-on: https://go-review.googlesource.com/c/go/+/439195 Reviewed-by: Ian Lance Taylor <[email protected]> Auto-Submit: Bryan Mills <[email protected]> Run-TryBot: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
What version of Go are you using (
go version
)?https://pkg.go.dev/[email protected]
Does this issue reproduce with the latest release?
Yes.
What did you do?
For #50436, I'm attempting to unblock reads on a
*File
returned byos.Pipe
while it is being read concurrently by a user-controlled goroutine. The user-controlled goroutine may legitimately call theClose
method, and may expect to be able to access other methods (such asSetDeadline
) via type-assertion.What did you expect to see?
Given #6270, #7970, #9307, #17647 and https://go.dev/cl/65490, I expected the documentation for `*os.File to describe which methods are safe to invoke concurrently and under what conditions.
What did you see instead?
The only mention of concurrency I could find in https://pkg.go.dev/[email protected] says this:
That seems to imply that at least some of the
File
methods may be invoked concurrently, but isn't explicit about which ones.I see unsynchronized writes in the
Close
implementation on bothunix
andplan9
(but maybe notwindows
?); it's not obvious to me which other methods are or aren't safe.(CC @rsc @ianlancetaylor @robpike from previous
*File
race conditions.)The text was updated successfully, but these errors were encountered: