Skip to content

Commit 9298bc0

Browse files
authored
fix: panic: close of closed channel (#5939)
1 parent 75d4ce3 commit 9298bc0

File tree

3 files changed

+20
-15
lines changed

3 files changed

+20
-15
lines changed

pkg/goanalysis/runner.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package goanalysis
66

77
import (
8+
"context"
89
"encoding/gob"
910
"fmt"
1011
"go/token"
@@ -259,18 +260,20 @@ func (r *runner) analyze(pkgs []*packages.Package, analyzers []*analysis.Analyze
259260
debugf("Analyzing at most %d packages in parallel", gomaxprocs)
260261

261262
loadSem := make(chan struct{}, gomaxprocs)
262-
stopChan := make(chan struct{}, 1)
263263

264264
debugf("There are %d initial and %d total packages", len(initialPkgs), len(loadingPackages))
265265

266+
ctx, cancel := context.WithCancel(context.Background())
267+
defer cancel()
268+
266269
var wg sync.WaitGroup
267270

268271
for _, lp := range loadingPackages {
269272
if lp.isInitial {
270273
wg.Add(1)
271274

272275
go func(lp *loadingPackage) {
273-
lp.analyzeRecursive(stopChan, r.loadMode, loadSem)
276+
lp.analyzeRecursive(ctx, cancel, r.loadMode, loadSem)
274277

275278
wg.Done()
276279
}(lp)

pkg/goanalysis/runner_action.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ func (actAlloc *actionAllocator) alloc() *action {
2929
return act
3030
}
3131

32-
func (act *action) waitUntilDependingAnalyzersWorked(ctx context.Context, stopChan chan struct{}) {
32+
func (act *action) waitUntilDependingAnalyzersWorked(ctx context.Context) {
3333
for _, dep := range act.Deps {
3434
if dep.Package == act.Package {
3535
select {
36-
case <-stopChan:
37-
return
3836
case <-ctx.Done():
3937
return
4038
case <-dep.analysisDoneCh:

pkg/goanalysis/runner_loadingpackage.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type loadingPackage struct {
4141
decUseMutex sync.Mutex
4242
}
4343

44-
func (lp *loadingPackage) analyzeRecursive(stopChan chan struct{}, loadMode LoadMode, loadSem chan struct{}) {
44+
func (lp *loadingPackage) analyzeRecursive(ctx context.Context, cancel context.CancelFunc, loadMode LoadMode, loadSem chan struct{}) {
4545
lp.analyzeOnce.Do(func() {
4646
// Load the direct dependencies, in parallel.
4747
var wg sync.WaitGroup
@@ -50,24 +50,30 @@ func (lp *loadingPackage) analyzeRecursive(stopChan chan struct{}, loadMode Load
5050

5151
for _, imp := range lp.imports {
5252
go func(imp *loadingPackage) {
53-
imp.analyzeRecursive(stopChan, loadMode, loadSem)
53+
imp.analyzeRecursive(ctx, cancel, loadMode, loadSem)
5454

5555
wg.Done()
5656
}(imp)
5757
}
5858

5959
wg.Wait()
6060

61-
lp.analyze(stopChan, loadMode, loadSem)
61+
lp.analyze(ctx, cancel, loadMode, loadSem)
6262
})
6363
}
6464

65-
func (lp *loadingPackage) analyze(stopChan chan struct{}, loadMode LoadMode, loadSem chan struct{}) {
65+
func (lp *loadingPackage) analyze(ctx context.Context, cancel context.CancelFunc, loadMode LoadMode, loadSem chan struct{}) {
6666
loadSem <- struct{}{}
6767
defer func() {
6868
<-loadSem
6969
}()
7070

71+
select {
72+
case <-ctx.Done():
73+
return
74+
default:
75+
}
76+
7177
// Save memory on unused more fields.
7278
defer lp.decUse(loadMode < LoadModeWholeProgram)
7379

@@ -85,16 +91,14 @@ func (lp *loadingPackage) analyze(stopChan chan struct{}, loadMode LoadMode, loa
8591
return
8692
}
8793

88-
actsWg, ctx := errgroup.WithContext(context.Background())
94+
actsWg, ctxGroup := errgroup.WithContext(ctx)
8995

9096
for _, act := range lp.actions {
9197
actsWg.Go(func() error {
92-
act.waitUntilDependingAnalyzersWorked(ctx, stopChan)
98+
act.waitUntilDependingAnalyzersWorked(ctxGroup)
9399

94100
select {
95-
case <-stopChan:
96-
return nil
97-
case <-ctx.Done():
101+
case <-ctxGroup.Done():
98102
return nil
99103
default:
100104
}
@@ -107,7 +111,7 @@ func (lp *loadingPackage) analyze(stopChan chan struct{}, loadMode LoadMode, loa
107111

108112
err := actsWg.Wait()
109113
if err != nil {
110-
close(stopChan)
114+
cancel()
111115
}
112116
}
113117

0 commit comments

Comments
 (0)