Commit 8c896aa4 authored by Bryan C. Mills's avatar Bryan C. Mills

cmd/go/internal/lockedfile: add a sync.Mutex to lockedfile.Mutex

The compiler (and race detector) don't interpret locking a file as a
synchronization operation, so we add an explicit (and redundant)
sync.Mutex to make that property clear.

The additional synchronization makes it safe to parallelize the tests
in cmd/go/internal/modfetch/coderepo_test.go, which cuts the wall time
of that test by around 50%.

Updates #30550

Change-Id: Ief3479020ebf9e0fee524a4aae5568697727c683
Reviewed-on: https://go-review.googlesource.com/c/go/+/170597
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarDaniel Martí <mvdan@mvdan.cc>
Reviewed-by: default avatarJay Conrod <jayconrod@google.com>
parent b0bcd7ae
...@@ -7,6 +7,7 @@ package lockedfile ...@@ -7,6 +7,7 @@ package lockedfile
import ( import (
"fmt" "fmt"
"os" "os"
"sync"
) )
// A Mutex provides mutual exclusion within and across processes by locking a // A Mutex provides mutual exclusion within and across processes by locking a
...@@ -21,7 +22,8 @@ import ( ...@@ -21,7 +22,8 @@ import (
// must not be copied after first use. The Path field must be set before first // must not be copied after first use. The Path field must be set before first
// use and must not be change thereafter. // use and must not be change thereafter.
type Mutex struct { type Mutex struct {
Path string // The path to the well-known lock file. Must be non-empty. Path string // The path to the well-known lock file. Must be non-empty.
mu sync.Mutex // A redundant mutex. The race detector doesn't know about file locking, so in tests we may need to lock something that it understands.
} }
// MutexAt returns a new Mutex with Path set to the given non-empty path. // MutexAt returns a new Mutex with Path set to the given non-empty path.
...@@ -56,5 +58,10 @@ func (mu *Mutex) Lock() (unlock func(), err error) { ...@@ -56,5 +58,10 @@ func (mu *Mutex) Lock() (unlock func(), err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return func() { f.Close() }, nil mu.mu.Lock()
return func() {
mu.mu.Unlock()
f.Close()
}, nil
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment