Work on making DatagramConn implement net.Conn

This commit is contained in:
eyedeekay
2025-05-29 18:49:54 -04:00
parent 38182694c5
commit 1cfdd98e18
3 changed files with 20 additions and 11 deletions

View File

@ -69,16 +69,14 @@ func (c *DatagramConn) Close() error {
c.closed = true
// Close reader and writer
// Close reader and writer - these are owned by this connection
if c.reader != nil {
c.reader.Close()
}
// Close the session
if err := c.session.Close(); err != nil {
logger.WithError(err).Error("Failed to close session")
return oops.Errorf("failed to close datagram connection: %w", err)
}
// DO NOT close the session - it's a shared resource that may be used by other connections
// The session should be closed by the code that created it, not by individual connections
// that use it. This follows the principle that the creator owns the resource.
logger.Debug("Successfully closed DatagramConn")
return nil

View File

@ -46,14 +46,21 @@ func (r *DatagramReader) Close() error {
logger.Debug("Closing DatagramReader")
r.closed = true
// Signal termination to receiveLoop and wait for it to exit
// Signal termination to receiveLoop
close(r.closeChan)
// Give receiveLoop time to detect the close signal and exit
// before closing the channels it might be writing to
time.Sleep(10 * time.Millisecond)
// Wait for receiveLoop to signal it has exited by closing doneChan
// This ensures proper synchronization without arbitrary delays
select {
case <-r.doneChan:
// receiveLoop has confirmed it stopped
case <-time.After(5 * time.Second):
// Timeout protection - log warning but continue cleanup
logger.Warn("Timeout waiting for receive loop to stop")
}
// Now safe to close the receiver channels
// Now safe to close the receiver channels since receiveLoop has stopped
close(r.recvChan)
close(r.errorChan)
@ -66,6 +73,9 @@ func (r *DatagramReader) receiveLoop() {
logger := log.WithField("session_id", r.session.ID())
logger.Debug("Starting receive loop")
// Ensure we signal completion when this loop exits
r.doneChan = make(chan struct{})
for {
// Check for closure in a non-blocking way first
select {

View File

@ -23,6 +23,7 @@ type DatagramReader struct {
recvChan chan *Datagram
errorChan chan error
closeChan chan struct{}
doneChan chan struct{}
closed bool
mu sync.RWMutex
}