Skip to content

Commit 252d76a

Browse files
committed
Fix deadlock when closing pipe
Signed-off-by: Mathieu Champlon <[email protected]>
1 parent bdc6c11 commit 252d76a

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

pipe.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,9 +574,11 @@ func (l *win32PipeListener) Accept() (net.Conn, error) {
574574

575575
func (l *win32PipeListener) Close() error {
576576
select {
577-
case l.closeCh <- 1:
578-
<-l.doneCh
579577
case <-l.doneCh:
578+
case <-l.closeCh:
579+
default:
580+
close(l.closeCh)
581+
<-l.doneCh
580582
}
581583
return nil
582584
}

pipe_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,3 +646,43 @@ func TestListenConnectRace(t *testing.T) {
646646
wg.Wait()
647647
}
648648
}
649+
650+
func TestCloseRace(t *testing.T) {
651+
for i := 0; i < 200 && !t.Failed(); i++ {
652+
l, err := ListenPipe(testPipeName, &PipeConfig{MessageMode: true})
653+
if err != nil {
654+
t.Fatal(err)
655+
}
656+
go func() {
657+
for {
658+
c, err := l.Accept()
659+
if err != nil {
660+
return
661+
}
662+
b, err := io.ReadAll(c)
663+
if err != nil {
664+
t.Error(err)
665+
return
666+
}
667+
_, _ = c.Write(b)
668+
_ = c.Close()
669+
}
670+
}()
671+
672+
c, err := DialPipe(testPipeName, nil)
673+
if err != nil {
674+
t.Fatal(err)
675+
}
676+
if _, err = c.Write([]byte("hello")); err != nil {
677+
t.Fatal(err)
678+
}
679+
if err := c.(CloseWriter).CloseWrite(); err != nil {
680+
t.Fatal(err)
681+
}
682+
if _, err := io.ReadAll(c); err != nil {
683+
t.Fatal(err)
684+
}
685+
_ = c.Close()
686+
_ = l.Close()
687+
}
688+
}

0 commit comments

Comments
 (0)