diff --git a/p2p/server.go b/p2p/server.go index 9b9effaf6..924296176 100644 --- a/p2p/server.go +++ b/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