5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-26 10:41:40 +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())
for {
var sock net.Conn
var err error
// Listen in a separate goroutine, as that way it does not block us from
// receiving "stop" events
go func() { go func() {
sock, err = l.Listener.Accept() <-l.stop
accepted <- true l.Listener.Close()
}() }()
// Wait for either an accepted connection, or a message telling us to stop defer l.Stop()
// the TCP listener for {
select { sock, err := l.Listener.Accept()
case <-accepted:
if err != nil { if err != nil {
t.link.core.log.Errorln("Failed to accept connection:", err) t.link.core.log.Errorln("Failed to accept connection:", err)
return return
} }
t.waitgroup.Add(1) t.waitgroup.Add(1)
go t.handler(sock, true, nil) 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
}
} }
} }