Skip to content

Commit 53412a2

Browse files
committed
Fix race condition of log after close
Not all resources were cleaned up immediately after a peer connection was closed. DataChannels could have a goroutine exit after Close() prior to this.
1 parent 3a29464 commit 53412a2

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

peer/channel.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func (c *Channel) init() {
135135

136136
c.conn.dcDisconnectListeners.Add(1)
137137
c.conn.dcFailedListeners.Add(1)
138+
c.conn.dcClosedWaitGroup.Add(1)
138139
go func() {
139140
var err error
140141
// A DataChannel can disconnect multiple times, so this needs to loop.
@@ -274,6 +275,7 @@ func (c *Channel) closeWithError(err error) error {
274275
close(c.sendMore)
275276
c.conn.dcDisconnectListeners.Sub(1)
276277
c.conn.dcFailedListeners.Sub(1)
278+
c.conn.dcClosedWaitGroup.Done()
277279

278280
if c.rwc != nil {
279281
_ = c.rwc.Close()

peer/conn.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ type Conn struct {
113113
dcDisconnectListeners atomic.Uint32
114114
dcFailedChannel chan struct{}
115115
dcFailedListeners atomic.Uint32
116+
dcClosedWaitGroup sync.WaitGroup
116117

117118
localCandidateChannel chan webrtc.ICECandidateInit
118119
localSessionDescriptionChannel chan webrtc.SessionDescription
@@ -125,11 +126,10 @@ type Conn struct {
125126
pingEchoChan *Channel
126127
pingEchoOnce sync.Once
127128
pingEchoError error
128-
129-
pingMutex sync.Mutex
130-
pingOnce sync.Once
131-
pingChan *Channel
132-
pingError error
129+
pingMutex sync.Mutex
130+
pingOnce sync.Once
131+
pingChan *Channel
132+
pingError error
133133
}
134134

135135
func (c *Conn) init() error {
@@ -502,5 +502,10 @@ func (c *Conn) CloseWithError(err error) error {
502502
// this call will return an error that isn't typed. We don't check the error because
503503
// closing an already closed connection isn't an issue for us.
504504
_ = c.rtc.Close()
505+
506+
// Waits for all DataChannels' to exit before officially labeling as closed.
507+
// All logging, goroutines, and async functionality is cleaned up after this.
508+
c.dcClosedWaitGroup.Wait()
509+
505510
return err
506511
}

0 commit comments

Comments
 (0)