Przeglądaj źródła

p2p: wait for listener goroutines on shutdown (#20569)

* p2p: wait for goroutine exit, fixes #20558

* p2p: wait for all slots on exit

Co-authored-by: Martin Holst Swende <martin@swende.se>
Felix Lange 5 lat temu
rodzic
commit
fcafa0baa5
1 zmienionych plików z 11 dodań i 1 usunięć
  1. 11 1
      p2p/server.go

+ 11 - 1
p2p/server.go

@@ -864,9 +864,9 @@ func (srv *Server) maxDialedConns() int {
 // listenLoop runs in its own goroutine and accepts
 // inbound connections.
 func (srv *Server) listenLoop() {
-	defer srv.loopWG.Done()
 	srv.log.Debug("TCP listener up", "addr", srv.listener.Addr())
 
+	// The slots channel limits accepts of new connections.
 	tokens := defaultMaxPendingPeers
 	if srv.MaxPendingPeers > 0 {
 		tokens = srv.MaxPendingPeers
@@ -876,6 +876,15 @@ func (srv *Server) listenLoop() {
 		slots <- struct{}{}
 	}
 
+	// Wait for slots to be returned on exit. This ensures all connection goroutines
+	// are down before listenLoop returns.
+	defer srv.loopWG.Done()
+	defer func() {
+		for i := 0; i < cap(slots); i++ {
+			<-slots
+		}
+	}()
+
 	for {
 		// Wait for a free slot before accepting.
 		<-slots
@@ -891,6 +900,7 @@ func (srv *Server) listenLoop() {
 				continue
 			} else if err != nil {
 				srv.log.Debug("Read error", "err", err)
+				slots <- struct{}{}
 				return
 			}
 			break