diff --git a/gather.go b/gather.go index 88a7b29..0f6cff7 100644 --- a/gather.go +++ b/gather.go @@ -51,17 +51,18 @@ func (a *Agent) GatherCandidates() error { a.gatherCandidateCancel() // Cancel previous gathering routine ctx, cancel := context.WithCancel(ctx) a.gatherCandidateCancel = cancel - a.gatherCandidateDone = make(chan struct{}) + done := make(chan struct{}) + a.gatherCandidateDone = done - go a.gatherCandidates(ctx) + go a.gatherCandidates(ctx, done) }); runErr != nil { return runErr } return gatherErr } -func (a *Agent) gatherCandidates(ctx context.Context) { - defer close(a.gatherCandidateDone) +func (a *Agent) gatherCandidates(ctx context.Context, done chan struct{}) { + defer close(done) if err := a.setGatheringState(GatheringStateGathering); err != nil { //nolint:contextcheck a.log.Warnf("failed to set gatheringState to GatheringStateGathering: %v", err) return diff --git a/gather_test.go b/gather_test.go index 01876c9..81bc116 100644 --- a/gather_test.go +++ b/gather_test.go @@ -87,6 +87,34 @@ func TestListenUDP(t *testing.T) { assert.NoError(t, a.Close()) } +func TestGatherConcurrency(t *testing.T) { + report := test.CheckRoutines(t) + defer report() + + lim := test.TimeOut(time.Second * 30) + defer lim.Stop() + + a, err := NewAgent(&AgentConfig{ + NetworkTypes: []NetworkType{NetworkTypeUDP4, NetworkTypeUDP6}, + IncludeLoopback: true, + }) + assert.NoError(t, err) + + candidateGathered, candidateGatheredFunc := context.WithCancel(context.Background()) + assert.NoError(t, a.OnCandidate(func(c Candidate) { + candidateGatheredFunc() + })) + + // tesing for panic + for i := 0; i < 10; i++ { + _ = a.GatherCandidates() + } + + <-candidateGathered.Done() + + assert.NoError(t, a.Close()) +} + func TestLoopbackCandidate(t *testing.T) { report := test.CheckRoutines(t) defer report()