Prevent writable race. (#2388)

It is possible that onBindAndConnectedChanged gets executed in such a
way that `writable` does not have the correct value in some very rare
timing case (i. e. case like two executions of the function is racing
and one atomic was read on first exeuction and second execution runs and
sets `writable` and then first execution completes the sets `writable`
to incorrect value based on stale read of first execution).

Prevent it by executing under bind lock.
This commit is contained in:
Raja Subramanian authored and GitHub committed 2024-01-16 12:15:13 +05:30
1 parent 5b4848e772
commit f29a28611b
1 file changed
+5 -2
+5 -2
View File
@@ -411,6 +411,7 @@ func (d *DownTrack) Bind(t webrtc.TrackLocalContext) (webrtc.RTPCodecParameters,
d.onBinding(nil)
}
d.bound.Store(true)
d.onBindAndConnectedChange()
d.bindLock.Unlock()
// Bind is called under RTPSender.mu lock, call the RTPSender.GetParameters in goroutine to avoid deadlock
@@ -425,9 +426,7 @@ func (d *DownTrack) Bind(t webrtc.TrackLocalContext) (webrtc.RTPCodecParameters,
}()
d.forwarder.DetermineCodec(d.codec, d.params.Receiver.HeaderExtensions())
d.params.Logger.Debugw("downtrack bound")
d.onBindAndConnectedChange()
return codec, nil
}
@@ -435,8 +434,10 @@ func (d *DownTrack) Bind(t webrtc.TrackLocalContext) (webrtc.RTPCodecParameters,
// Unbind implements the teardown logic when the track is no longer needed. This happens
// because a track has been stopped.
func (d *DownTrack) Unbind(_ webrtc.TrackLocalContext) error {
d.bindLock.Lock()
d.bound.Store(false)
d.onBindAndConnectedChange()
d.bindLock.Unlock()
return nil
}
@@ -1577,10 +1578,12 @@ func (d *DownTrack) handleRTCP(bytes []byte) {
}
func (d *DownTrack) SetConnected() {
d.bindLock.Lock()
if !d.connected.Swap(true) {
d.onBindAndConnectedChange()
}
d.params.Logger.Debugw("downtrack connected")
d.bindLock.Unlock()
}
// SetActivePaddingOnMuteUpTrack will enable padding on the track when its uptrack is muted.