Skip to content

Commit 5a75f7c

Browse files
bradfitzodeke-em
authored andcommitted
net/http: fix Server.Shutdown race where it could miss an active connection
Wait for Listeners to drop to zero too, not just conns. Fixes #33313 Change-Id: I09350ae38087990d368dcf9302fbde3e95c02fcd Reviewed-on: https://go-review.googlesource.com/c/go/+/213442 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Hasit Bhatt <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent eacdf76 commit 5a75f7c

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

src/net/http/serve_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5980,8 +5980,11 @@ type countCloseListener struct {
59805980
}
59815981

59825982
func (p *countCloseListener) Close() error {
5983-
atomic.AddInt32(&p.closes, 1)
5984-
return nil
5983+
var err error
5984+
if n := atomic.AddInt32(&p.closes, 1); n == 1 && p.Listener != nil {
5985+
err = p.Listener.Close()
5986+
}
5987+
return err
59855988
}
59865989

59875990
// Issue 24803: don't call Listener.Close on Server.Shutdown.

src/net/http/server.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2680,7 +2680,7 @@ func (srv *Server) Shutdown(ctx context.Context) error {
26802680
ticker := time.NewTicker(shutdownPollInterval)
26812681
defer ticker.Stop()
26822682
for {
2683-
if srv.closeIdleConns() {
2683+
if srv.closeIdleConns() && srv.numListeners() == 0 {
26842684
return lnerr
26852685
}
26862686
select {
@@ -2702,6 +2702,12 @@ func (srv *Server) RegisterOnShutdown(f func()) {
27022702
srv.mu.Unlock()
27032703
}
27042704

2705+
func (s *Server) numListeners() int {
2706+
s.mu.Lock()
2707+
defer s.mu.Unlock()
2708+
return len(s.listeners)
2709+
}
2710+
27052711
// closeIdleConns closes all idle connections and reports whether the
27062712
// server is quiescent.
27072713
func (s *Server) closeIdleConns() bool {
@@ -2734,7 +2740,6 @@ func (s *Server) closeListenersLocked() error {
27342740
if cerr := (*ln).Close(); cerr != nil && err == nil {
27352741
err = cerr
27362742
}
2737-
delete(s.listeners, ln)
27382743
}
27392744
return err
27402745
}

0 commit comments

Comments
 (0)