From 89dd8ce1fdc0f27d316ffe66afe32d0446264b40 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sat, 19 Dec 2015 22:28:37 -0500 Subject: [PATCH] Return an error in Accept() when root is closed. As reported in #4, when the root listener is closed, calling Accept on mux'd listeners would block forever, instead of returning an error. This is because of a bug introduced in b90740d. This commit fixes #4 by selecting on both donec and connc of muxed listeners. Added a test case to guard against this issue. --- cmux.go | 7 ++++--- cmux_test.go | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cmux.go b/cmux.go index 76a5bae..8f268e4 100644 --- a/cmux.go +++ b/cmux.go @@ -158,11 +158,12 @@ type muxListener struct { } func (l muxListener) Accept() (c net.Conn, err error) { - c, ok := <-l.connc - if !ok { + select { + case c = <-l.connc: + return c, nil + case <-l.donec: return nil, ErrListenerClosed } - return c, nil } type MuxConn struct { diff --git a/cmux_test.go b/cmux_test.go index ad40be8..6b950ce 100644 --- a/cmux_test.go +++ b/cmux_test.go @@ -180,4 +180,8 @@ func TestClosed(t *testing.T) { lis := mux.Match(Any()).(muxListener) close(lis.donec) mux.serve(closerConn{}) + _, err := lis.Accept() + if _, ok := err.(errListenerClosed); !ok { + t.Errorf("expected errListenerClosed got %v", err) + } }