Skip to content

Commit c4c8686

Browse files
author
Edward Muller
committed
Fix leaking wg.Done() and <-ioLimit
Fixes golang/go#32368 There were several returns in this function that could leak both the wg.Done() and <-ioLimit. This refactors them into defers close to their counterparts. Additionally I refactored the function to favor early returns over nested if statements.
1 parent b3315ee commit c4c8686

File tree

1 file changed

+26
-21
lines changed

1 file changed

+26
-21
lines changed

internal/lsp/cache/parse.go

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -60,33 +60,38 @@ func (imp *importer) parseFiles(filenames []string) ([]*ast.File, []error) {
6060

6161
wg.Add(1)
6262
go func(i int, filename string) {
63+
defer wg.Done()
64+
6365
ioLimit <- true // wait
66+
defer func() {
67+
<-ioLimit // signal done
68+
}()
6469

65-
if gof.ast != nil {
70+
if gof.ast != nil { // already have an ast
6671
parsed[i], errors[i] = gof.ast, nil
67-
} else {
68-
// We don't have a cached AST for this file.
69-
gof.read(imp.ctx)
70-
if gof.fc.Error != nil {
71-
return
72-
}
73-
src := gof.fc.Data
74-
if src == nil {
75-
parsed[i], errors[i] = nil, fmt.Errorf("No source for %v", filename)
76-
} else {
77-
// ParseFile may return both an AST and an error.
78-
parsed[i], errors[i] = parseFile(imp.fset, filename, src)
72+
return
73+
}
74+
75+
// No cached AST for this file, so try parsing it.
76+
gof.read(imp.ctx)
77+
if gof.fc.Error != nil { // file content error, so abort
78+
return
79+
}
7980

80-
// Fix any badly parsed parts of the AST.
81-
if file := parsed[i]; file != nil {
82-
tok := imp.fset.File(file.Pos())
83-
imp.view.fix(imp.ctx, parsed[i], tok, src)
84-
}
85-
}
81+
src := gof.fc.Data
82+
if len(src) == 0 { // no source
83+
parsed[i], errors[i] = nil, fmt.Errorf("No source for %v", filename)
84+
return
8685
}
8786

88-
<-ioLimit // signal
89-
wg.Done()
87+
// ParseFile may return a partial AST AND an error.
88+
parsed[i], errors[i] = parseFile(imp.fset, filename, src)
89+
90+
// Fix any badly parsed parts of the AST.
91+
if file := parsed[i]; file != nil {
92+
tok := imp.fset.File(file.Pos())
93+
imp.view.fix(imp.ctx, parsed[i], tok, src)
94+
}
9095
}(i, filename)
9196
}
9297
wg.Wait()

0 commit comments

Comments
 (0)