@@ -1550,6 +1550,7 @@ func (c *HostClient) acquireConn(reqTimeout time.Duration, connectionClose bool)
15501550 case <- w .ready :
15511551 return w .conn , w .err
15521552 case <- tc .C :
1553+ c .connsWait .failedWaiters .Add (1 )
15531554 if timeoutOverridden {
15541555 return nil , ErrTimeout
15551556 }
@@ -1695,6 +1696,7 @@ func (c *HostClient) decConnsCount() {
16951696 dialed = true
16961697 break
16971698 }
1699+ c .connsWait .failedWaiters .Add (- 1 )
16981700 }
16991701 }
17001702 if ! dialed {
@@ -1749,6 +1751,7 @@ func (c *HostClient) releaseConn(cc *clientConn) {
17491751 delivered = w .tryDeliver (cc , nil )
17501752 break
17511753 }
1754+ c .connsWait .failedWaiters .Add (- 1 )
17521755 }
17531756 }
17541757 if ! delivered {
@@ -2104,11 +2107,17 @@ type wantConnQueue struct {
21042107 head []* wantConn
21052108 tail []* wantConn
21062109 headPos int
2110+ // failedWaiters is the number of waiters in the head or tail queue,
2111+ // but is invalid.
2112+ // These state waiters cannot truly be considered as waiters; the current
2113+ // implementation does not immediately remove them when they become
2114+ // invalid but instead only marks them.
2115+ failedWaiters atomic.Int64
21072116}
21082117
21092118// len returns the number of items in the queue.
21102119func (q * wantConnQueue ) len () int {
2111- return len (q .head ) - q .headPos + len (q .tail )
2120+ return len (q .head ) - q .headPos + len (q .tail ) - int ( q . failedWaiters . Load ())
21122121}
21132122
21142123// pushBack adds w to the back of the queue.
@@ -2152,6 +2161,7 @@ func (q *wantConnQueue) clearFront() (cleaned bool) {
21522161 return cleaned
21532162 }
21542163 q .popFront ()
2164+ q .failedWaiters .Add (- 1 )
21552165 cleaned = true
21562166 }
21572167}
0 commit comments