Browse Source

Merge pull request #16 from freelancer/master

Fix for bug that can cause leaked goroutines
Brad Fitzpatrick 11 năm trước cách đây
mục cha
commit
5f7d3b9504
1 tập tin đã thay đổi với 16 bổ sung18 xóa
  1. 16 18
      memcache/memcache.go

+ 16 - 18
memcache/memcache.go

@@ -234,6 +234,10 @@ type ConnectTimeoutError struct {
 	Addr net.Addr
 }
 
+type netConnectionTimeoutError interface {
+	Timeout() bool
+}
+
 func (cte *ConnectTimeoutError) Error() string {
 	return "memcache: connect timeout to " + cte.Addr.String()
 }
@@ -243,25 +247,19 @@ func (c *Client) dial(addr net.Addr) (net.Conn, error) {
 		cn  net.Conn
 		err error
 	}
-	ch := make(chan connError)
-	go func() {
-		nc, err := net.Dial(addr.Network(), addr.String())
-		ch <- connError{nc, err}
-	}()
-	select {
-	case ce := <-ch:
-		return ce.cn, ce.err
-	case <-time.After(c.netTimeout()):
-		// Too slow. Fall through.
-	}
-	// Close the conn if it does end up finally coming in
-	go func() {
-		ce := <-ch
-		if ce.err == nil {
-			ce.cn.Close()
+
+	nc, err := net.DialTimeout(addr.Network(), addr.String(), c.netTimeout())
+	if err == nil {
+		return nc, nil
+	}
+
+	if terr, ok := err.(netConnectionTimeoutError); ok {
+		if terr.Timeout() {
+			return nil, &ConnectTimeoutError{addr}
 		}
-	}()
-	return nil, &ConnectTimeoutError{addr}
+	}
+
+	return nil, err
 }
 
 func (c *Client) getConn(addr net.Addr) (*conn, error) {