mirror of
https://github.com/pion/ice.git
synced 2025-12-24 13:38:03 +08:00
Fix a deadlock in TaskLoop
This commit is contained in:
@@ -85,6 +85,8 @@ func (l *Loop) Run(ctx context.Context, t func(context.Context)) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-l.done:
|
||||
return ErrClosed
|
||||
case l.tasks <- task{t, done}:
|
||||
<-done
|
||||
|
||||
|
||||
60
internal/taskloop/taskloop_test.go
Normal file
60
internal/taskloop/taskloop_test.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package taskloop
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRunReturnsErrClosedWhenLoopClosing(t *testing.T) {
|
||||
loop := New(func() {})
|
||||
|
||||
blockStarted := make(chan struct{})
|
||||
releaseBlock := make(chan struct{})
|
||||
go func() {
|
||||
_ = loop.Run(context.Background(), func(context.Context) {
|
||||
close(blockStarted)
|
||||
<-releaseBlock
|
||||
})
|
||||
}()
|
||||
<-blockStarted
|
||||
|
||||
var secondRan atomic.Bool
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
errCh <- loop.Run(context.Background(), func(context.Context) {
|
||||
secondRan.Store(true)
|
||||
})
|
||||
}()
|
||||
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
|
||||
closeDone := make(chan struct{})
|
||||
go func() {
|
||||
loop.Close()
|
||||
close(closeDone)
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-errCh:
|
||||
assert.ErrorIs(t, err, ErrClosed)
|
||||
case <-time.After(time.Second):
|
||||
assert.Fail(t, "Run did not return after loop close")
|
||||
}
|
||||
|
||||
close(releaseBlock)
|
||||
|
||||
select {
|
||||
case <-closeDone:
|
||||
case <-time.After(time.Second):
|
||||
assert.Fail(t, "Close did not return")
|
||||
}
|
||||
|
||||
assert.False(t, secondRan.Load(), "second task should not excute after loop is closed")
|
||||
}
|
||||
Reference in New Issue
Block a user