From dd5645bebff44f6b88780bb949022a09eadd7dae Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 25 Aug 2016 15:18:19 -0400 Subject: [PATCH] Avoid goroutine leak in clientconn Prior to this change, it was possible for `DialContext` to return `(nil, err)` without properly closing the `ClientConn`, resulting in an unavoidable leak of the `resetAddrConn` goroutine. --- clientconn.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/clientconn.go b/clientconn.go index ccaff94a..1d3b46c6 100644 --- a/clientconn.go +++ b/clientconn.go @@ -234,13 +234,13 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * defer func() { select { case <-ctx.Done(): - if conn != nil { - conn.Close() - } - conn = nil - err = ctx.Err() + conn, err = nil, ctx.Err() default: } + + if err != nil { + cc.Close() + } }() for _, opt := range opts { @@ -296,11 +296,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * return nil, ctx.Err() case err := <-waitC: if err != nil { - cc.Close() return nil, err } case <-timeoutCh: - cc.Close() return nil, ErrClientConnTimeout } // If balancer is nil or balancer.Notify() is nil, ok will be false here.