diff options
author | Colin Cross <ccross@android.com> | 2016-12-09 10:29:05 -0800 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2016-12-09 10:35:33 -0800 |
commit | 0ce142ca05952b911855a0f87a56e5a30f5a1f76 (patch) | |
tree | 55ea95dbf7e6d856271c49e5d1a776d29daff70a /context.go | |
parent | 0f1fa92e86c7540a19088ec7fb2eed66f9028c16 (diff) | |
download | android_build_blueprint-0ce142ca05952b911855a0f87a56e5a30f5a1f76.tar.gz android_build_blueprint-0ce142ca05952b911855a0f87a56e5a30f5a1f76.tar.bz2 android_build_blueprint-0ce142ca05952b911855a0f87a56e5a30f5a1f76.zip |
Fix data race when applying replacements
Mutator context goroutines appending directly to the global Context's
replacements list causes a data race. Send them over a channel
instead.
The renames and replacements are local to the mutator, so move them
out of Context and into the runMutator method.
Change-Id: I797edb1e27ee29f8946c58101b40fcfb50a32eb9
Diffstat (limited to 'context.go')
-rw-r--r-- | context.go | 68 |
1 files changed, 38 insertions, 30 deletions
@@ -101,10 +101,6 @@ type Context struct { // set lazily by sortedModuleNames cachedSortedModuleNames []string - // List of pending renames and replacements to apply after the mutator pass - renames []rename - replacements []replace - globs map[string]GlobPath globLock sync.Mutex @@ -1706,16 +1702,22 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo, newModuleInfo[k] = v } + type globalStateChange struct { + reverse []reverseDep + rename []rename + replace []replace + } + reverseDeps := make(map[*moduleInfo][]depInfo) + var rename []rename + var replace []replace errsCh := make(chan []error) - reverseDepsCh := make(chan []reverseDep) + globalStateCh := make(chan globalStateChange) newModulesCh := make(chan []*moduleInfo) done := make(chan bool) c.depsModified = 0 - c.renames = nil - c.replacements = nil visit := func(module *moduleInfo) bool { if module.splitModules != nil { @@ -1755,8 +1757,12 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo, newModulesCh <- mctx.newModules } - if len(mctx.reverseDeps) > 0 { - reverseDepsCh <- mctx.reverseDeps + if len(mctx.reverseDeps) > 0 || len(mctx.replace) > 0 || len(mctx.rename) > 0 { + globalStateCh <- globalStateChange{ + reverse: mctx.reverseDeps, + replace: mctx.replace, + rename: mctx.rename, + } } return false @@ -1768,10 +1774,12 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo, select { case newErrs := <-errsCh: errs = append(errs, newErrs...) - case newReverseDeps := <-reverseDepsCh: - for _, r := range newReverseDeps { + case globalStateChange := <-globalStateCh: + for _, r := range globalStateChange.reverse { reverseDeps[r.module] = append(reverseDeps[r.module], r.dep) } + replace = append(replace, globalStateChange.replace...) + rename = append(rename, globalStateChange.rename...) case newModules := <-newModulesCh: for _, m := range newModules { newModuleInfo[m.logicModule] = m @@ -1821,7 +1829,12 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo, c.depsModified++ } - errs = c.handleRenamesAndReplacements() + errs = c.handleRenames(rename) + if len(errs) > 0 { + return errs + } + + errs = c.handleReplacements(replace) if len(errs) > 0 { return errs } @@ -2124,36 +2137,25 @@ type rename struct { name string } -func (c *Context) rename(group *moduleGroup, name string) { - c.renames = append(c.renames, rename{group, name}) -} - -func (c *Context) replaceDependencies(module *moduleInfo, name string) { +func (c *Context) moduleMatchingVariant(module *moduleInfo, name string) *moduleInfo { targets := c.modulesFromName(name) if targets == nil { - panic(fmt.Errorf("ReplaceDependencies called with non-existant name %q", name)) + return nil } - var target *moduleInfo for _, m := range targets { if module.variantName == m.variantName { - target = m - break + return m } } - if target == nil { - panic(fmt.Errorf("ReplaceDependencies could not find identical variant %q for module %q", - module.variantName, name)) - } - - c.replacements = append(c.replacements, replace{target, module}) + return nil } -func (c *Context) handleRenamesAndReplacements() []error { +func (c *Context) handleRenames(renames []rename) []error { var errs []error - for _, rename := range c.renames { + for _, rename := range renames { group, name := rename.group, rename.name if name == group.name { continue @@ -2180,7 +2182,12 @@ func (c *Context) handleRenamesAndReplacements() []error { group.name = name } - for _, replace := range c.replacements { + return errs +} + +func (c *Context) handleReplacements(replacements []replace) []error { + var errs []error + for _, replace := range replacements { for _, m := range replace.from.reverseDeps { for i, d := range m.directDeps { if d.module == replace.from { @@ -2191,6 +2198,7 @@ func (c *Context) handleRenamesAndReplacements() []error { atomic.AddUint32(&c.depsModified, 1) } + return errs } |