5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-22 22:20:27 +00:00

fix race between listener accepting and shutting down

This commit is contained in:
Arceliar 2019-09-19 19:50:45 -05:00
parent eeb34ce4e4
commit f9163a56b6

View File

@ -184,7 +184,6 @@ func (t *tcp) listener(l *TcpListener, listenaddr string) {
t.mutex.Unlock() t.mutex.Unlock()
} }
// And here we go! // And here we go!
accepted := make(chan bool)
defer func() { defer func() {
t.link.core.log.Infoln("Stopping TCP listener on:", l.Listener.Addr().String()) t.link.core.log.Infoln("Stopping TCP listener on:", l.Listener.Addr().String())
l.Listener.Close() l.Listener.Close()
@ -193,29 +192,19 @@ func (t *tcp) listener(l *TcpListener, listenaddr string) {
t.mutex.Unlock() t.mutex.Unlock()
}() }()
t.link.core.log.Infoln("Listening for TCP on:", l.Listener.Addr().String()) t.link.core.log.Infoln("Listening for TCP on:", l.Listener.Addr().String())
go func() {
<-l.stop
l.Listener.Close()
}()
defer l.Stop()
for { for {
var sock net.Conn sock, err := l.Listener.Accept()
var err error if err != nil {
// Listen in a separate goroutine, as that way it does not block us from t.link.core.log.Errorln("Failed to accept connection:", err)
// receiving "stop" events
go func() {
sock, err = l.Listener.Accept()
accepted <- true
}()
// Wait for either an accepted connection, or a message telling us to stop
// the TCP listener
select {
case <-accepted:
if err != nil {
t.link.core.log.Errorln("Failed to accept connection:", err)
return
}
t.waitgroup.Add(1)
go t.handler(sock, true, nil)
case <-l.stop:
// FIXME this races with the goroutine that Accepts a TCP connection, may leak connections when a listener is removed
return return
} }
t.waitgroup.Add(1)
go t.handler(sock, true, nil)
} }
} }