Fix close race in DatagramSession

This commit is contained in:
eyedeekay
2025-06-01 18:07:09 -04:00
parent b609d06306
commit 88c2168ee0

View File

@ -63,24 +63,38 @@ func (r *DatagramReader) Close() error {
// Improved channel closing with better error handling // Improved channel closing with better error handling
func (r *DatagramReader) safeCloseChannel() { func (r *DatagramReader) safeCloseChannel() {
// Close channels in order of dependency // Use defer to ensure recovery from any panics
defer func() { defer func() {
if recover() != nil { if recover() != nil {
// Channels already closed - expected in concurrent scenarios // Channels already closed - expected in concurrent scenarios
} }
}() }()
// First close the done channel // Close done channel first with protection
select { select {
case <-r.doneChan: case <-r.doneChan:
// Already closed // Already closed or received signal
default: default:
close(r.doneChan) // Try to close, but protect against concurrent closure
select {
case r.doneChan <- struct{}{}:
// Successfully signaled
default:
// Channel full or closed, close it
close(r.doneChan)
}
} }
// Then close data channels // Close data channels with protection against double-close
close(r.recvChan) func() {
close(r.errorChan) defer func() { recover() }()
close(r.recvChan)
}()
func() {
defer func() { recover() }()
close(r.errorChan)
}()
} }
func (r *DatagramReader) receiveLoop() { func (r *DatagramReader) receiveLoop() {