aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Smelkov <kirr@nexedi.com>2016-12-20 12:02:39 +0300
committerRuss Cox <rsc@golang.org>2016-12-21 15:08:26 +0000
commitd296c3235d47ab1a0e5077dfcfbc3e14854e38c5 (patch)
treec31da223566056c6598e6bd87b7e3a0deaa12465
parent0ef4815150782a47cde25937349f9c4441b0e78e (diff)
downloadgo-d296c3235d47ab1a0e5077dfcfbc3e14854e38c5.tar.gz
go-d296c3235d47ab1a0e5077dfcfbc3e14854e38c5.zip
io: fix PipeWriter.Close to wake up Writes
Since commit cc62bed0 (CL 994043) the pipe deadlock when doing Read+Close or Write+Close on same end was fixed, alas with test for Read+Close case only. Then commit 6d6f3381 (CL 4252057) made a thinko: in the writer path p.werr is checked for != nil and then err is set but there is no break from waiting loop unlike break is there in similar condition for reader. Together with having only Read+Close case tested that made it to leave reintroduced Write+Close deadlock unnoticed. Fix it. Implicitly this also fixes net.Pipe to conform to semantic of net.Conn interface where Close is documented to unblock any blocked Read or Write operations. No test added to net/ since net.Pipe tests are "Assuming that the underlying io.Pipe implementation is solid and we're just testing the net wrapping". The test added in this patch should be enough to cover the breakage. Fixes #18401 Updates #18170 Change-Id: I9e9460b3fd7d220bbe60b726accf86f352aed8d4 Reviewed-on: https://go-review.googlesource.com/34637 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
-rw-r--r--src/io/pipe.go1
-rw-r--r--src/io/pipe_test.go12
2 files changed, 13 insertions, 0 deletions
diff --git a/src/io/pipe.go b/src/io/pipe.go
index 6145872391..b6e7755f64 100644
--- a/src/io/pipe.go
+++ b/src/io/pipe.go
@@ -85,6 +85,7 @@ func (p *pipe) write(b []byte) (n int, err error) {
}
if p.werr != nil {
err = ErrClosedPipe
+ break
}
p.wwait.Wait()
}
diff --git a/src/io/pipe_test.go b/src/io/pipe_test.go
index b16e653069..95930e86a4 100644
--- a/src/io/pipe_test.go
+++ b/src/io/pipe_test.go
@@ -247,6 +247,18 @@ func TestPipeWriteClose(t *testing.T) {
}
}
+// Test close on Write side during Write.
+func TestPipeWriteClose2(t *testing.T) {
+ c := make(chan int, 1)
+ _, w := Pipe()
+ go delayClose(t, w, c, pipeTest{})
+ n, err := w.Write(make([]byte, 64))
+ <-c
+ if n != 0 || err != ErrClosedPipe {
+ t.Errorf("write to closed pipe: %v, %v want %v, %v", n, err, 0, ErrClosedPipe)
+ }
+}
+
func TestWriteEmpty(t *testing.T) {
r, w := Pipe()
go func() {