mirror of
https://github.com/go-i2p/go-sam-go.git
synced 2025-06-30 20:53:03 -04:00
Fix close race in DatagramSession
This commit is contained in:
@ -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() {
|
||||||
|
Reference in New Issue
Block a user