repositories / bugabinga.net
bugabinga.net
personal infrastructure for bugabinga!
owned by admin
services/luci/internal/servicelock/lock.go
Rawpackage servicelock
import (
"errors"
"os"
"path/filepath"
"syscall"
)
var ErrHeld = errors.New("luci serve consumer already holds this data directory")
type Lock struct{ file *os.File }
// Acquire exclusively locks one Luci data directory until Close or process exit.
func Acquire(dataDir string) (Lock, error) {
if err := os.MkdirAll(dataDir, 0o755); err != nil {
return Lock{}, err
}
file, err := os.OpenFile(filepath.Join(dataDir, ".serve.lock"), os.O_CREATE|os.O_RDWR, 0o644)
if err != nil {
return Lock{}, err
}
if err := syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
_ = file.Close()
if errors.Is(err, syscall.EWOULDBLOCK) || errors.Is(err, syscall.EAGAIN) {
return Lock{}, ErrHeld
}
return Lock{}, err
}
return Lock{file: file}, nil
}
func (l Lock) Close() error {
if l.file == nil {
return nil
}
return l.file.Close()
}