Skip to content

Commit e840173

Browse files
committed
api: fix concurrency issues
Might do some duplicated work but at least it will be actually sound.
1 parent 13c37af commit e840173

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

api.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ func newCompilation(opts Options) *compilation {
3939
sourcesByIndex: make(map[int]*sources.Source),
4040
outputsByIndex: make(map[int]struct{}),
4141
astsByIndex: make(map[int]*ast.Stylesheet),
42-
lockersByIndex: make(map[int]*sync.Mutex),
4342
result: newResult(),
4443
reporter: logging.DefaultReporter,
4544
transforms: opts.Transforms,
@@ -66,12 +65,14 @@ type compilation struct {
6665
sources map[string]int
6766
nextIndex int
6867

69-
sourcesByIndex map[int]*sources.Source
70-
astsByIndex map[int]*ast.Stylesheet
68+
sourcesByIndexMu sync.RWMutex
69+
sourcesByIndex map[int]*sources.Source
70+
71+
astsByIndexMu sync.RWMutex
72+
astsByIndex map[int]*ast.Stylesheet
7173

7274
// outputsByIndex is the set of sources to write outputs for.
7375
outputsByIndex map[int]struct{}
74-
lockersByIndex map[int]*sync.Mutex
7576

7677
result *Result
7778

@@ -110,13 +111,11 @@ func (c *compilation) addSource(path string) (int, error) {
110111
c.sourcesMu.Lock()
111112
i := c.nextIndex
112113
c.sources[abs] = i
113-
locker := &sync.Mutex{}
114-
c.lockersByIndex[i] = locker
115114
c.sourcesMu.Unlock()
116115

117-
locker.Lock()
118-
defer locker.Unlock()
116+
c.sourcesByIndexMu.Lock()
119117
c.sourcesByIndex[i] = source
118+
c.sourcesByIndexMu.Unlock()
120119

121120
c.nextIndex++
122121
return i, nil
@@ -159,16 +158,16 @@ func (c *compilation) parseFile(file string, hasOutput bool) *ast.Stylesheet {
159158
c.outputsByIndex[idx] = struct{}{}
160159
}
161160

162-
// Grab the lock for this source, since multiple callers might try
163-
// to parse the same file.
164-
locker := c.lockersByIndex[idx]
165-
locker.Lock()
166-
defer locker.Unlock()
161+
c.astsByIndexMu.RLock()
167162
if ss, ok := c.astsByIndex[idx]; ok {
163+
c.astsByIndexMu.RUnlock()
168164
return ss
169165
}
166+
c.astsByIndexMu.RUnlock()
170167

168+
c.sourcesByIndexMu.RLock()
171169
source := c.sourcesByIndex[idx]
170+
c.sourcesByIndexMu.RUnlock()
172171
ss, err := parser.Parse(source)
173172
if err != nil {
174173
c.addError(err)
@@ -213,7 +212,9 @@ func (c *compilation) parseFile(file string, hasOutput bool) *ast.Stylesheet {
213212
}
214213

215214
ss = transformer.Transform(ss, opts)
215+
c.astsByIndexMu.Lock()
216216
c.astsByIndex[idx] = ss
217+
c.astsByIndexMu.Unlock()
217218
return ss
218219
}
219220

0 commit comments

Comments
 (0)