-
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
io: Close and CloseWithError overwrite the error stored in a pipe #24283
Comments
I'm fairly certain that this change will break many people. However, I do agree the proposed semantics is probably preferred. In generally, the first encountered error is more accurate than some later error. For example,
The |
Hi @dsnet, My hunch was that most code which is hitting this case is probably unknowingly broken, and this is in effect fixing it. I guess we need to decide whether this would be considered a bug or not. Thanks, looking more closely I see that concurrent Read or Write calls still need mutual exclusion around the error values, but that doesn't really matter much for the discussion of the error semantics. |
/cc @ianlancetaylor what do you think? Proposal worthy or Go2? |
I would like to understand why we can't just change the code today. Calling |
Currently calling I can run a regression test to see measure the impact of this change. |
Only the first Close should have any effect. Anything else is a bug. |
Change https://golang.org/cl/187197 mentions this issue: |
The current implementation allows multiple calls `Close` and `CloseWithError` in every side of the pipe, as a result, the original error can be overwritten. This CL fixes this behavior adding an error existence check on `atomicError` type and keeping the first error still available. Fixes golang#24283 Change-Id: Iefe8f758aeb775309424365f8177511062514150 GitHub-Last-Rev: b559540 GitHub-Pull-Request: golang#33239 Reviewed-on: https://go-review.googlesource.com/c/go/+/187197 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com> Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
The current implementation allows multiple calls `Close` and `CloseWithError` in every side of the pipe, as a result, the original error can be overwritten. This CL fixes this behavior adding an error existence check on `atomicError` type and keeping the first error still available. Fixes golang#24283 Change-Id: Iefe8f758aeb775309424365f8177511062514150 GitHub-Last-Rev: b559540 GitHub-Pull-Request: golang#33239 Reviewed-on: https://go-review.googlesource.com/c/go/+/187197 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com> Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Calling
Close
afterCloseWithError
(orCloseWithError
multiple times) overwrites the stored error inio.pipe
.Opening an issue for discussion first, since there is test coverage verifying this behavior, though it seems to only be there to check the
atomic.Value
, and it does subtly change the API.Since pipes are often used concurrently, and multiple calls to
Close
usually have no effect, users would often expect the following code to be deterministic:But in this case, if there is an error and the
PipeReader
executesRead
immediately afterCloseWithError
it will get the stored error from theCopy
, but oncedefer pw.Close
executes the error is set back toEOF
.Moving the error assignment into the
pipe.once
would make the above work,and probably also allow the removal of thesync.Value
fields, since the errors are protected by the done chan and thesync.Once
.The text was updated successfully, but these errors were encountered: