p2p: wait for all slots on exit

This commit is contained in:
Felix Lange 2020-01-16 12:09:02 +01:00
parent 5ba0dd8880
commit cc02f5517d

View file

@ -866,21 +866,25 @@ func (srv *Server) maxDialedConns() int {
func (srv *Server) listenLoop() { func (srv *Server) listenLoop() {
srv.log.Debug("TCP listener up", "addr", srv.listener.Addr()) srv.log.Debug("TCP listener up", "addr", srv.listener.Addr())
// The slots channel limits accepts of new connections.
tokens := defaultMaxPendingPeers tokens := defaultMaxPendingPeers
if srv.MaxPendingPeers > 0 { if srv.MaxPendingPeers > 0 {
tokens = srv.MaxPendingPeers tokens = srv.MaxPendingPeers
} }
slots := make(chan struct{}, tokens) slots := make(chan struct{}, tokens)
defer func() {
// Wait for a slot. This is to wait for any goroutine(s) doing srv.SetupConn
// to complete before exiting
<-slots
srv.loopWG.Done()
}()
for i := 0; i < tokens; i++ { for i := 0; i < tokens; i++ {
slots <- struct{}{} 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 { for {
// Wait for a free slot before accepting. // Wait for a free slot before accepting.
<-slots <-slots
@ -896,6 +900,7 @@ func (srv *Server) listenLoop() {
continue continue
} else if err != nil { } else if err != nil {
srv.log.Debug("Read error", "err", err) srv.log.Debug("Read error", "err", err)
slots <- struct{}{}
return return
} }
break break