commit 4f41ff66898913697507fdf8ebb75d811715b81a from: Stephen Day via: GitHub date: Fri Aug 12 19:31:16 2016 UTC Merge pull request #21 from nilium/fix-close-error-race Fix race-y channel close/error assignment commit - 87c6cf4550e8bf9dac847f1c6437e453aadef7c8 commit + 4f41ff66898913697507fdf8ebb75d811715b81a blob - 80b1e9479bb7f916e95e8c9e0734ed4a889ac404 blob + 2c5ec955994e20ddbba22d86b7c3b9c475d23344 --- server.go +++ server.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "net" + "sync" "time" "golang.org/x/net/context" @@ -53,8 +54,10 @@ type conn struct { session Session ch Channel handler Handler - closed chan struct{} - err error // terminal error for the conn + + once sync.Once + closed chan struct{} + err error // terminal error for the conn } // activeRequest includes information about the active request. @@ -233,17 +236,14 @@ func (c *conn) Close() error { } func (c *conn) CloseWithError(err error) error { - select { - case <-c.closed: - return c.err - default: - close(c.closed) + c.once.Do(func() { if err == nil { - c.err = err - } else { - c.err = ErrClosed + err = ErrClosed } - return c.err - } + c.err = err + close(c.closed) + }) + + return c.err }