Skip to content

Commit

Permalink
fix: double-checked locking fail (#392)
Browse files Browse the repository at this point in the history
We use double-checked locking to avoid locks on the fast-path, but I
modified the behaviour in #390 to cache the result before the lock,
removing the second check. Face palm.

This fixes #391
  • Loading branch information
alecthomas authored Nov 15, 2023
1 parent 44cb709 commit 880e21c
Showing 1 changed file with 6 additions and 9 deletions.
15 changes: 6 additions & 9 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,10 @@ func (s *State) removeRecursive(b *ui.Task, dest string) error {
//
// If the package has already been extracted, this is a no-op
func (s *State) CacheAndUnpack(b *ui.Task, p *manifest.Package) error {
// Check if the package is up-to-date, and if so, return before acquiring the lock
isExtracted := s.isExtracted(p)
var areBinariesLinked bool
if isExtracted {
areBinariesLinked = s.areBinariesLinked(p)
}
if (isExtracted && areBinariesLinked) || p.Source == "/" {
// Double-checked locking. We check without the lock first, and then check
// again after acquiring the lock.

if (s.isExtracted(p) && s.areBinariesLinked(p)) || p.Source == "/" {
return nil
}

Expand All @@ -300,13 +297,13 @@ func (s *State) CacheAndUnpack(b *ui.Task, p *manifest.Package) error {
}
defer lock.Release(b)

if !isExtracted {
if !s.isExtracted(p) {
if err := s.extract(b, p); err != nil {
return errors.WithStack(err)
}
}

if !areBinariesLinked {
if !s.areBinariesLinked(p) {
if err := s.linkBinaries(p); err != nil {
return errors.WithStack(err)
}
Expand Down

0 comments on commit 880e21c

Please sign in to comment.