@@ -39,23 +39,28 @@ type loadingPackage struct {
3939 decUseMutex sync.Mutex
4040}
4141
42- func (lp * loadingPackage ) analyzeRecursive (loadMode LoadMode , loadSem chan struct {}) {
42+ func (lp * loadingPackage ) analyzeRecursive (stopChan chan struct {}, loadMode LoadMode , loadSem chan struct {}) {
4343 lp .analyzeOnce .Do (func () {
4444 // Load the direct dependencies, in parallel.
4545 var wg sync.WaitGroup
46+
4647 wg .Add (len (lp .imports ))
48+
4749 for _ , imp := range lp .imports {
4850 go func (imp * loadingPackage ) {
49- imp .analyzeRecursive (loadMode , loadSem )
51+ imp .analyzeRecursive (stopChan , loadMode , loadSem )
52+
5053 wg .Done ()
5154 }(imp )
5255 }
56+
5357 wg .Wait ()
54- lp .analyze (loadMode , loadSem )
58+
59+ lp .analyze (stopChan , loadMode , loadSem )
5560 })
5661}
5762
58- func (lp * loadingPackage ) analyze (loadMode LoadMode , loadSem chan struct {}) {
63+ func (lp * loadingPackage ) analyze (stopChan chan struct {}, loadMode LoadMode , loadSem chan struct {}) {
5964 loadSem <- struct {}{}
6065 defer func () {
6166 <- loadSem
@@ -65,27 +70,46 @@ func (lp *loadingPackage) analyze(loadMode LoadMode, loadSem chan struct{}) {
6570 defer lp .decUse (loadMode < LoadModeWholeProgram )
6671
6772 if err := lp .loadWithFacts (loadMode ); err != nil {
68- werr := fmt .Errorf ("failed to load package %s: %w" , lp .pkg .Name , err )
6973 // Don't need to write error to errCh, it will be extracted and reported on another layer.
7074 // Unblock depending on actions and propagate error.
7175 for _ , act := range lp .actions {
7276 close (act .analysisDoneCh )
73- act .Err = werr
77+
78+ act .Err = fmt .Errorf ("failed to load package %s: %w" , lp .pkg .Name , err )
7479 }
80+
7581 return
7682 }
7783
7884 var actsWg sync.WaitGroup
85+
7986 actsWg .Add (len (lp .actions ))
87+
8088 for _ , act := range lp .actions {
8189 go func (act * action ) {
8290 defer actsWg .Done ()
8391
84- act .waitUntilDependingAnalyzersWorked ()
92+ act .waitUntilDependingAnalyzersWorked (stopChan )
93+
94+ select {
95+ case <- stopChan :
96+ return
97+ default :
98+ }
8599
86100 act .analyzeSafe ()
101+
102+ select {
103+ case <- stopChan :
104+ return
105+ default :
106+ if act .Err != nil {
107+ close (stopChan )
108+ }
109+ }
87110 }(act )
88111 }
112+
89113 actsWg .Wait ()
90114}
91115
0 commit comments