Do not invoke OnBufferedAmountLow after close

This commit is contained in:
Joe Turki
2025-12-05 18:30:51 +02:00
parent f3177f8486
commit 62f61018b1
3 changed files with 66 additions and 6 deletions

View File

@@ -707,13 +707,23 @@ func (d *DataChannel) OnBufferedAmountLow(f func()) {
d.mu.Lock() d.mu.Lock()
defer d.mu.Unlock() defer d.mu.Unlock()
d.onBufferedAmountLow = func() { onBufferedAmountLow := d.makeBufferedAmountLowHandler(f)
go f() d.onBufferedAmountLow = onBufferedAmountLow
}
if d.dataChannel != nil { if d.dataChannel != nil {
d.dataChannel.OnBufferedAmountLow(func() { d.dataChannel.OnBufferedAmountLow(onBufferedAmountLow)
go f() }
}) }
func (d *DataChannel) makeBufferedAmountLowHandler(f func()) func() {
return func() {
go func() {
if d.ReadyState() != DataChannelStateOpen {
return
}
f()
}()
} }
} }

View File

@@ -855,3 +855,49 @@ func TestOnBufferedAmountLowDeadlock(t *testing.T) {
<-gotAllMessages.Done() <-gotAllMessages.Done()
closePairNow(t, offerPC, answerPC) closePairNow(t, offerPC, answerPC)
} }
func TestOnBufferedAmountLowRespectsReadyState(t *testing.T) {
t.Run("fires when open", func(t *testing.T) {
dc := &DataChannel{}
dc.setReadyState(DataChannelStateOpen)
called := make(chan struct{}, 1)
dc.OnBufferedAmountLow(func() {
called <- struct{}{}
})
dc.mu.RLock()
handler := dc.onBufferedAmountLow
dc.mu.RUnlock()
handler()
select {
case <-called:
case <-time.After(time.Second):
assert.Fail(t, "expected OnBufferedAmountLow to fire when open")
}
})
t.Run("skips when not open", func(t *testing.T) {
dc := &DataChannel{}
dc.setReadyState(DataChannelStateClosing)
called := make(chan struct{}, 1)
dc.OnBufferedAmountLow(func() {
called <- struct{}{}
})
dc.mu.RLock()
handler := dc.onBufferedAmountLow
dc.mu.RUnlock()
handler()
select {
case <-called:
assert.Fail(t, "expected OnBufferedAmountLow to be ignored when not open")
case <-time.After(50 * time.Millisecond):
}
})
}

View File

@@ -301,6 +301,10 @@ func (d *DataChannel) OnBufferedAmountLow(f func()) {
defer oldHandler.Release() defer oldHandler.Release()
} }
onBufferedAmountLow := js.FuncOf(func(this js.Value, args []js.Value) any { onBufferedAmountLow := js.FuncOf(func(this js.Value, args []js.Value) any {
if d.ReadyState() != DataChannelStateOpen {
return js.Undefined()
}
go f() go f()
return js.Undefined() return js.Undefined()
}) })