diff options
| author | Taras Madan <tarasmadan@google.com> | 2025-01-22 16:07:17 +0100 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2025-01-23 10:42:36 +0000 |
| commit | 7b4377ad9d8a7205416df8d6217ef2b010f89481 (patch) | |
| tree | e6fec4fd12ff807a16d847923f501075bf71d16c /vendor/github.com/gofrs | |
| parent | 475a4c203afb8b7d3af51c4fd32bb170ff32a45e (diff) | |
vendor: delete
Diffstat (limited to 'vendor/github.com/gofrs')
| -rw-r--r-- | vendor/github.com/gofrs/flock/.gitignore | 24 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/.golangci.yml | 114 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/LICENSE | 28 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/Makefile | 15 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/README.md | 45 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/SECURITY.md | 21 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/build.sh | 18 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/flock.go | 206 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/flock_others.go | 40 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/flock_unix.go | 210 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/flock_unix_fcntl.go | 393 | ||||
| -rw-r--r-- | vendor/github.com/gofrs/flock/flock_windows.go | 158 |
12 files changed, 0 insertions, 1272 deletions
diff --git a/vendor/github.com/gofrs/flock/.gitignore b/vendor/github.com/gofrs/flock/.gitignore deleted file mode 100644 index daf913b1b..000000000 --- a/vendor/github.com/gofrs/flock/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/gofrs/flock/.golangci.yml b/vendor/github.com/gofrs/flock/.golangci.yml deleted file mode 100644 index 3ad88a38f..000000000 --- a/vendor/github.com/gofrs/flock/.golangci.yml +++ /dev/null @@ -1,114 +0,0 @@ -run: - timeout: 10m - -linters: - enable: - - asasalint - - bidichk - - dogsled - - dupword - - durationcheck - - err113 - - errname - - errorlint - - fatcontext - - forbidigo - - gocheckcompilerdirectives - - gochecknoinits - - gocritic - - godot - - godox - - gofumpt - - goheader - - goimports - - gomoddirectives - - goprintffuncname - - gosec - - inamedparam - - interfacebloat - - ireturn - - mirror - - misspell - - nolintlint - - revive - - stylecheck - - tenv - - testifylint - - thelper - - unconvert - - unparam - - usestdlibvars - - whitespace - -linters-settings: - misspell: - locale: US - godox: - keywords: - - FIXME - goheader: - template: |- - Copyright 2015 Tim Heckman. All rights reserved. - Copyright 2018-{{ YEAR }} The Gofrs. All rights reserved. - Use of this source code is governed by the BSD 3-Clause - license that can be found in the LICENSE file. - gofumpt: - extra-rules: true - gocritic: - enabled-tags: - - diagnostic - - style - - performance - disabled-checks: - - paramTypeCombine # already handle by gofumpt.extra-rules - - whyNoLint # already handle by nonolint - - unnamedResult - - hugeParam - - sloppyReassign - - rangeValCopy - - octalLiteral - - ptrToRefParam - - appendAssign - - ruleguard - - httpNoBody - - exposedSyncMutex - - revive: - rules: - - name: struct-tag - - name: blank-imports - - name: context-as-argument - - name: context-keys-type - - name: dot-imports - - name: error-return - - name: error-strings - - name: error-naming - - name: exported - - name: if-return - - name: increment-decrement - - name: var-naming - - name: var-declaration - - name: package-comments - - name: range - - name: receiver-naming - - name: time-naming - - name: unexported-return - - name: indent-error-flow - - name: errorf - - name: empty-block - - name: superfluous-else - - name: unused-parameter - - name: unreachable-code - - name: redefines-builtin-id - -issues: - exclude-use-default: true - max-issues-per-linter: 0 - max-same-issues: 0 - -output: - show-stats: true - sort-results: true - sort-order: - - linter - - file diff --git a/vendor/github.com/gofrs/flock/LICENSE b/vendor/github.com/gofrs/flock/LICENSE deleted file mode 100644 index 7de525bf0..000000000 --- a/vendor/github.com/gofrs/flock/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2018-2024, The Gofrs -Copyright (c) 2015-2020, Tim Heckman -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of gofrs nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gofrs/flock/Makefile b/vendor/github.com/gofrs/flock/Makefile deleted file mode 100644 index 65c139d68..000000000 --- a/vendor/github.com/gofrs/flock/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: lint test test_race build_cross_os - -default: lint test build_cross_os - -test: - go test -v -cover ./... - -test_race: - CGO_ENABLED=1 go test -v -race ./... - -lint: - golangci-lint run - -build_cross_os: - ./build.sh diff --git a/vendor/github.com/gofrs/flock/README.md b/vendor/github.com/gofrs/flock/README.md deleted file mode 100644 index f7ca0dd9c..000000000 --- a/vendor/github.com/gofrs/flock/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# flock - -[](https://pkg.go.dev/github.com/gofrs/flock) -[](https://github.com/gofrs/flock/blob/main/LICENSE) -[](https://goreportcard.com/report/github.com/gofrs/flock) - -`flock` implements a thread-safe file lock. - -It also includes a non-blocking `TryLock()` function to allow locking without blocking execution. - -## Installation - -```bash -go get -u github.com/gofrs/flock -``` - -## Usage - -```go -import "github.com/gofrs/flock" - -fileLock := flock.New("/var/lock/go-lock.lock") - -locked, err := fileLock.TryLock() - -if err != nil { - // handle locking error -} - -if locked { - // do work - fileLock.Unlock() -} -``` - -For more detailed usage information take a look at the package API docs on -[GoDoc](https://pkg.go.dev/github.com/gofrs/flock). - -## License - -`flock` is released under the BSD 3-Clause License. See the [`LICENSE`](./LICENSE) file for more details. - -## Project History - -This project was originally `github.com/theckman/go-flock`, it was transferred to Gofrs by the original author [Tim Heckman ](https://github.com/theckman). diff --git a/vendor/github.com/gofrs/flock/SECURITY.md b/vendor/github.com/gofrs/flock/SECURITY.md deleted file mode 100644 index 01419bd59..000000000 --- a/vendor/github.com/gofrs/flock/SECURITY.md +++ /dev/null @@ -1,21 +0,0 @@ -# Security Policy - -## Supported Versions - -We support the latest version of this library. -We do not guarantee support of previous versions. - -If a defect is reported, it will generally be fixed on the latest version (provided it exists) irrespective of whether it was introduced in a prior version. - -## Reporting a Vulnerability - -To report a potential security vulnerability, please create a [security advisory](https://github.com/gofrs/flock/security/advisories/new). - -For us to respond to your report most effectively, please include any of the following: - -- Steps to reproduce or a proof-of-concept -- Any relevant information, including the versions used - -## Security Scorecard - -This project submits security [results](https://scorecard.dev/viewer/?uri=github.com/gofrs/flock) to the [OpenSSF Scorecard](https://securityscorecards.dev/). diff --git a/vendor/github.com/gofrs/flock/build.sh b/vendor/github.com/gofrs/flock/build.sh deleted file mode 100644 index 60f7809f0..000000000 --- a/vendor/github.com/gofrs/flock/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -e - -# Not supported by flock: -# - plan9/* -# - js/wasm -# - wasp1/wasm - -for row in $(go tool dist list -json | jq -r '.[] | @base64'); do - _jq() { - echo ${row} | base64 --decode | jq -r ${1} - } - - GOOS=$(_jq '.GOOS') - GOARCH=$(_jq '.GOARCH') - - echo "$GOOS/$GOARCH" - GOOS=$GOOS GOARCH=$GOARCH go build -done diff --git a/vendor/github.com/gofrs/flock/flock.go b/vendor/github.com/gofrs/flock/flock.go deleted file mode 100644 index ff942b228..000000000 --- a/vendor/github.com/gofrs/flock/flock.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2024 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -// Package flock implements a thread-safe interface for file locking. -// It also includes a non-blocking TryLock() function to allow locking -// without blocking execution. -// -// Package flock is released under the BSD 3-Clause License. See the LICENSE file -// for more details. -// -// While using this library, remember that the locking behaviors are not -// guaranteed to be the same on each platform. For example, some UNIX-like -// operating systems will transparently convert a shared lock to an exclusive -// lock. If you Unlock() the flock from a location where you believe that you -// have the shared lock, you may accidentally drop the exclusive lock. -package flock - -import ( - "context" - "io/fs" - "os" - "runtime" - "sync" - "time" -) - -type Option func(f *Flock) - -// SetFlag sets the flag used to create/open the file. -func SetFlag(flag int) Option { - return func(f *Flock) { - f.flag = flag - } -} - -// SetPermissions sets the OS permissions to set on the file. -func SetPermissions(perm fs.FileMode) Option { - return func(f *Flock) { - f.perm = perm - } -} - -// Flock is the struct type to handle file locking. All fields are unexported, -// with access to some of the fields provided by getter methods (Path() and Locked()). -type Flock struct { - path string - m sync.RWMutex - fh *os.File - l bool - r bool - - // flag is the flag used to create/open the file. - flag int - // perm is the OS permissions to set on the file. - perm fs.FileMode -} - -// New returns a new instance of *Flock. The only parameter -// it takes is the path to the desired lockfile. -func New(path string, opts ...Option) *Flock { - // create it if it doesn't exist, and open the file read-only. - flags := os.O_CREATE - switch runtime.GOOS { - case "aix", "solaris", "illumos": - // AIX cannot preform write-lock (i.e. exclusive) on a read-only file. - flags |= os.O_RDWR - default: - flags |= os.O_RDONLY - } - - f := &Flock{ - path: path, - flag: flags, - perm: fs.FileMode(0o600), - } - - for _, opt := range opts { - opt(f) - } - - return f -} - -// NewFlock returns a new instance of *Flock. The only parameter -// it takes is the path to the desired lockfile. -// -// Deprecated: Use New instead. -func NewFlock(path string) *Flock { - return New(path) -} - -// Close is equivalent to calling Unlock. -// -// This will release the lock and close the underlying file descriptor. -// It will not remove the file from disk, that's up to your application. -func (f *Flock) Close() error { - return f.Unlock() -} - -// Path returns the path as provided in NewFlock(). -func (f *Flock) Path() string { - return f.path -} - -// Locked returns the lock state (locked: true, unlocked: false). -// -// Warning: by the time you use the returned value, the state may have changed. -func (f *Flock) Locked() bool { - f.m.RLock() - defer f.m.RUnlock() - - return f.l -} - -// RLocked returns the read lock state (locked: true, unlocked: false). -// -// Warning: by the time you use the returned value, the state may have changed. -func (f *Flock) RLocked() bool { - f.m.RLock() - defer f.m.RUnlock() - - return f.r -} - -func (f *Flock) String() string { - return f.path -} - -// TryLockContext repeatedly tries to take an exclusive lock until one of the conditions is met: -// - TryLock succeeds -// - TryLock fails with error -// - Context Done channel is closed. -func (f *Flock) TryLockContext(ctx context.Context, retryDelay time.Duration) (bool, error) { - return tryCtx(ctx, f.TryLock, retryDelay) -} - -// TryRLockContext repeatedly tries to take a shared lock until one of the conditions is met: -// - TryRLock succeeds -// - TryRLock fails with error -// - Context Done channel is closed. -func (f *Flock) TryRLockContext(ctx context.Context, retryDelay time.Duration) (bool, error) { - return tryCtx(ctx, f.TryRLock, retryDelay) -} - -func tryCtx(ctx context.Context, fn func() (bool, error), retryDelay time.Duration) (bool, error) { - if ctx.Err() != nil { - return false, ctx.Err() - } - - for { - if ok, err := fn(); ok || err != nil { - return ok, err - } - - select { - case <-ctx.Done(): - return false, ctx.Err() - case <-time.After(retryDelay): - // try again - } - } -} - -func (f *Flock) setFh(flag int) error { - // open a new os.File instance - fh, err := os.OpenFile(f.path, flag, f.perm) - if err != nil { - return err - } - - // set the file handle on the struct - f.fh = fh - - return nil -} - -// resetFh resets file handle: -// - tries to close the file (ignore errors) -// - sets fh to nil. -func (f *Flock) resetFh() { - if f.fh == nil { - return - } - - _ = f.fh.Close() - - f.fh = nil -} - -// ensure the file handle is closed if no lock is held. -func (f *Flock) ensureFhState() { - if f.l || f.r || f.fh == nil { - return - } - - f.resetFh() -} - -func (f *Flock) reset() { - f.l = false - f.r = false - - f.resetFh() -} diff --git a/vendor/github.com/gofrs/flock/flock_others.go b/vendor/github.com/gofrs/flock/flock_others.go deleted file mode 100644 index 18b14f1bd..000000000 --- a/vendor/github.com/gofrs/flock/flock_others.go +++ /dev/null @@ -1,40 +0,0 @@ -//go:build (!unix && !windows) || plan9 - -package flock - -import ( - "errors" - "io/fs" -) - -func (f *Flock) Lock() error { - return &fs.PathError{ - Op: "Lock", - Path: f.Path(), - Err: errors.ErrUnsupported, - } -} - -func (f *Flock) RLock() error { - return &fs.PathError{ - Op: "RLock", - Path: f.Path(), - Err: errors.ErrUnsupported, - } -} - -func (f *Flock) Unlock() error { - return &fs.PathError{ - Op: "Unlock", - Path: f.Path(), - Err: errors.ErrUnsupported, - } -} - -func (f *Flock) TryLock() (bool, error) { - return false, f.Lock() -} - -func (f *Flock) TryRLock() (bool, error) { - return false, f.RLock() -} diff --git a/vendor/github.com/gofrs/flock/flock_unix.go b/vendor/github.com/gofrs/flock/flock_unix.go deleted file mode 100644 index cf8919c7a..000000000 --- a/vendor/github.com/gofrs/flock/flock_unix.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2024 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -//go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd - -package flock - -import ( - "errors" - "os" - - "golang.org/x/sys/unix" -) - -// Lock is a blocking call to try and take an exclusive file lock. -// It will wait until it is able to obtain the exclusive file lock. -// It's recommended that TryLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already exclusive-locked, -// this function short-circuits and returns immediately assuming it can take the mutex lock. -// -// If the *Flock has a shared lock (RLock), -// this may transparently replace the shared lock with an exclusive lock on some UNIX-like operating systems. -// Be careful when using exclusive locks in conjunction with shared locks (RLock()), -// because calling Unlock() may accidentally release the exclusive lock that was once a shared lock. -func (f *Flock) Lock() error { - return f.lock(&f.l, unix.LOCK_EX) -} - -// RLock is a blocking call to try and take a shared file lock. -// It will wait until it is able to obtain the shared file lock. -// It's recommended that TryRLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already shared-locked, -// this function short-circuits and returns immediately assuming it can take the mutex lock. -func (f *Flock) RLock() error { - return f.lock(&f.r, unix.LOCK_SH) -} - -func (f *Flock) lock(locked *bool, flag int) error { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return err - } - - defer f.ensureFhState() - } - - err := unix.Flock(int(f.fh.Fd()), flag) - if err != nil { - shouldRetry, reopenErr := f.reopenFDOnError(err) - if reopenErr != nil { - return reopenErr - } - - if !shouldRetry { - return err - } - - err = unix.Flock(int(f.fh.Fd()), flag) - if err != nil { - return err - } - } - - *locked = true - - return nil -} - -// Unlock is a function to unlock the file. -// This file takes a RW-mutex lock, -// so while it is running the Locked() and RLocked() functions will be blocked. -// -// This function short-circuits if we are unlocked already. -// If not, it calls unix.LOCK_UN on the file and closes the file descriptor. -// It does not remove the file from disk. It's up to your application to do. -// -// Please note, -// if your shared lock became an exclusive lock, -// this may unintentionally drop the exclusive lock if called by the consumer that believes they have a shared lock. -// Please see Lock() for more details. -func (f *Flock) Unlock() error { - f.m.Lock() - defer f.m.Unlock() - - // If we aren't locked or if the lockfile instance is nil - // just return a nil error because we are unlocked. - if (!f.l && !f.r) || f.fh == nil { - return nil - } - - // Mark the file as unlocked. - err := unix.Flock(int(f.fh.Fd()), unix.LOCK_UN) - if err != nil { - return err - } - - f.reset() - - return nil -} - -// TryLock is the preferred function for taking an exclusive file lock. -// This function takes an RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the exclusive file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being exclusive-locked. -func (f *Flock) TryLock() (bool, error) { - return f.try(&f.l, unix.LOCK_EX) -} - -// TryRLock is the preferred function for taking a shared file lock. -// This function takes an RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the shared file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being share-locked. -func (f *Flock) TryRLock() (bool, error) { - return f.try(&f.r, unix.LOCK_SH) -} - -func (f *Flock) try(locked *bool, flag int) (bool, error) { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return true, nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return false, err - } - - defer f.ensureFhState() - } - - var retried bool -retry: - err := unix.Flock(int(f.fh.Fd()), flag|unix.LOCK_NB) - - switch { - case errors.Is(err, unix.EWOULDBLOCK): - return false, nil - case err == nil: - *locked = true - return true, nil - } - - if !retried { - shouldRetry, reopenErr := f.reopenFDOnError(err) - if reopenErr != nil { - return false, reopenErr - } else if shouldRetry { - retried = true - goto retry - } - } - - return false, err -} - -// reopenFDOnError determines whether we should reopen the file handle in readwrite mode and try again. -// This comes from `util-linux/sys-utils/flock.c`: -// > Since Linux 3.4 (commit 55725513) -// > Probably NFSv4 where flock() is emulated by fcntl(). -// > https://github.com/util-linux/util-linux/blob/198e920aa24743ef6ace4e07cf6237de527f9261/sys-utils/flock.c#L374-L390 -func (f *Flock) reopenFDOnError(err error) (bool, error) { - if !errors.Is(err, unix.EIO) && !errors.Is(err, unix.EBADF) { - return false, nil - } - - st, err := f.fh.Stat() - if err != nil { - return false, nil - } - - if st.Mode()&f.perm != f.perm { - return false, nil - } - - f.resetFh() - - // reopen in read-write mode and set the file handle - err = f.setFh(f.flag | os.O_RDWR) - if err != nil { - return false, err - } - - return true, nil -} diff --git a/vendor/github.com/gofrs/flock/flock_unix_fcntl.go b/vendor/github.com/gofrs/flock/flock_unix_fcntl.go deleted file mode 100644 index ea007b47d..000000000 --- a/vendor/github.com/gofrs/flock/flock_unix_fcntl.go +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2024 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This code implements the filelock API using POSIX 'fcntl' locks, -// which attach to an (inode, process) pair rather than a file descriptor. -// To avoid unlocking files prematurely when the same file is opened through different descriptors, -// we allow only one read-lock at a time. -// -// This code is adapted from the Go package (go.22): -// https://github.com/golang/go/blob/release-branch.go1.22/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go - -//go:build aix || (solaris && !illumos) - -package flock - -import ( - "errors" - "io" - "io/fs" - "math/rand" - "sync" - "syscall" - "time" - - "golang.org/x/sys/unix" -) - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L28 -type lockType int16 - -// String returns the name of the function corresponding to lt -// (Lock, RLock, or Unlock). -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock.go#L67 -func (lt lockType) String() string { - switch lt { - case readLock: - return "RLock" - case writeLock: - return "Lock" - default: - return "Unlock" - } -} - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L30-L33 -const ( - readLock lockType = unix.F_RDLCK - writeLock lockType = unix.F_WRLCK -) - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L35 -type inode = uint64 - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L37-L40 -type inodeLock struct { - owner *Flock - queue []<-chan *Flock -} - -type cmdType int - -const ( - tryLock cmdType = unix.F_SETLK - waitLock cmdType = unix.F_SETLKW -) - -var ( - mu sync.Mutex - inodes = map[*Flock]inode{} - locks = map[inode]inodeLock{} -) - -// Lock is a blocking call to try and take an exclusive file lock. -// It will wait until it is able to obtain the exclusive file lock. -// It's recommended that TryLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already exclusive-locked, this function short-circuits and -// returns immediately assuming it can take the mutex lock. -// -// If the *Flock has a shared lock (RLock), -// this may transparently replace the shared lock with an exclusive lock on some UNIX-like operating systems. -// Be careful when using exclusive locks in conjunction with shared locks (RLock()), -// because calling Unlock() may accidentally release the exclusive lock that was once a shared lock. -func (f *Flock) Lock() error { - return f.lock(&f.l, writeLock) -} - -// RLock is a blocking call to try and take a shared file lock. -// It will wait until it is able to obtain the shared file lock. -// It's recommended that TryRLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already shared-locked, this function short-circuits and -// returns immediately assuming it can take the mutex lock. -func (f *Flock) RLock() error { - return f.lock(&f.r, readLock) -} - -func (f *Flock) lock(locked *bool, flag lockType) error { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return err - } - - defer f.ensureFhState() - } - - _, err := f.doLock(waitLock, flag, true) - if err != nil { - return err - } - - *locked = true - - return nil -} - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L48 -func (f *Flock) doLock(cmd cmdType, lt lockType, blocking bool) (bool, error) { - // POSIX locks apply per inode and process, - // and the lock for an inode is released when *any* descriptor for that inode is closed. - // So we need to synchronize access to each inode internally, - // and must serialize lock and unlock calls that refer to the same inode through different descriptors. - fi, err := f.fh.Stat() - if err != nil { - return false, err - } - - // Note(ldez): don't replace `syscall.Stat_t` by `unix.Stat_t` because `FileInfo.Sys()` returns `syscall.Stat_t` - ino := fi.Sys().(*syscall.Stat_t).Ino - - mu.Lock() - - if i, dup := inodes[f]; dup && i != ino { - mu.Unlock() - return false, &fs.PathError{ - Op: lt.String(), - Path: f.Path(), - Err: errors.New("inode for file changed since last Lock or RLock"), - } - } - - inodes[f] = ino - - var wait chan *Flock - - l := locks[ino] - - switch { - case l.owner == f: - // This file already owns the lock, but the call may change its lock type. - case l.owner == nil: - // No owner: it's ours now. - l.owner = f - - case !blocking: - // Already owned: cannot take the lock. - mu.Unlock() - return false, nil - - default: - // Already owned: add a channel to wait on. - wait = make(chan *Flock) - l.queue = append(l.queue, wait) - } - - locks[ino] = l - - mu.Unlock() - - if wait != nil { - wait <- f - } - - // Spurious EDEADLK errors arise on platforms that compute deadlock graphs at - // the process, rather than thread, level. Consider processes P and Q, with - // threads P.1, P.2, and Q.3. The following trace is NOT a deadlock, but will be - // reported as a deadlock on systems that consider only process granularity: - // - // P.1 locks file A. - // Q.3 locks file B. - // Q.3 blocks on file A. - // P.2 blocks on file B. (This is erroneously reported as a deadlock.) - // P.1 unlocks file A. - // Q.3 unblocks and locks file A. - // Q.3 unlocks files A and B. - // P.2 unblocks and locks file B. - // P.2 unlocks file B. - // - // These spurious errors were observed in practice on AIX and Solaris in - // cmd/go: see https://golang.org/issue/32817. - // - // We work around this bug by treating EDEADLK as always spurious. If there - // really is a lock-ordering bug between the interacting processes, it will - // become a livelock instead, but that's not appreciably worse than if we had - // a proper flock implementation (which generally does not even attempt to - // diagnose deadlocks). - // - // In the above example, that changes the trace to: - // - // P.1 locks file A. - // Q.3 locks file B. - // Q.3 blocks on file A. - // P.2 spuriously fails to lock file B and goes to sleep. - // P.1 unlocks file A. - // Q.3 unblocks and locks file A. - // Q.3 unlocks files A and B. - // P.2 wakes up and locks file B. - // P.2 unlocks file B. - // - // We know that the retry loop will not introduce a *spurious* livelock - // because, according to the POSIX specification, EDEADLK is only to be - // returned when “the lock is blocked by a lock from another process”. - // If that process is blocked on some lock that we are holding, then the - // resulting livelock is due to a real deadlock (and would manifest as such - // when using, for example, the flock implementation of this package). - // If the other process is *not* blocked on some other lock that we are - // holding, then it will eventually release the requested lock. - - nextSleep := 1 * time.Millisecond - const maxSleep = 500 * time.Millisecond - for { - err = setlkw(f.fh.Fd(), cmd, lt) - if !errors.Is(err, unix.EDEADLK) { - break - } - - time.Sleep(nextSleep) - - nextSleep += nextSleep - if nextSleep > maxSleep { - nextSleep = maxSleep - } - // Apply 10% jitter to avoid synchronizing collisions when we finally unblock. - nextSleep += time.Duration((0.1*rand.Float64() - 0.05) * float64(nextSleep)) - } - - if err != nil { - f.doUnlock() - - if cmd == tryLock && errors.Is(err, unix.EACCES) { - return false, nil - } - - return false, &fs.PathError{ - Op: lt.String(), - Path: f.Path(), - Err: err, - } - } - - return true, nil -} - -func (f *Flock) Unlock() error { - f.m.Lock() - defer f.m.Unlock() - - // If we aren't locked or if the lockfile instance is nil - // just return a nil error because we are unlocked. - if (!f.l && !f.r) || f.fh == nil { - return nil - } - - if err := f.doUnlock(); err != nil { - return err - } - - f.reset() - - return nil -} - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L163 -func (f *Flock) doUnlock() (err error) { - var owner *Flock - - mu.Lock() - - ino, ok := inodes[f] - if ok { - owner = locks[ino].owner - } - - mu.Unlock() - - if owner == f { - err = setlkw(f.fh.Fd(), waitLock, unix.F_UNLCK) - } - - mu.Lock() - - l := locks[ino] - - if len(l.queue) == 0 { - // No waiters: remove the map entry. - delete(locks, ino) - } else { - // The first waiter is sending us their file now. - // Receive it and update the queue. - l.owner = <-l.queue[0] - l.queue = l.queue[1:] - locks[ino] = l - } - - delete(inodes, f) - - mu.Unlock() - - return err -} - -// TryLock is the preferred function for taking an exclusive file lock. -// This function takes an RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the exclusive file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being exclusive-locked. -func (f *Flock) TryLock() (bool, error) { - return f.try(&f.l, writeLock) -} - -// TryRLock is the preferred function for taking a shared file lock. -// This function takes an RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the shared file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being share-locked. -func (f *Flock) TryRLock() (bool, error) { - return f.try(&f.r, readLock) -} - -func (f *Flock) try(locked *bool, flag lockType) (bool, error) { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return true, nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return false, err - } - - defer f.ensureFhState() - } - - hasLock, err := f.doLock(tryLock, flag, false) - if err != nil { - return false, err - } - - *locked = hasLock - - return hasLock, nil -} - -// setlkw calls FcntlFlock with cmd for the entire file indicated by fd. -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L198 -func setlkw(fd uintptr, cmd cmdType, lt lockType) error { - for { - err := unix.FcntlFlock(fd, int(cmd), &unix.Flock_t{ - Type: int16(lt), - Whence: io.SeekStart, - Start: 0, - Len: 0, // All bytes. - }) - if !errors.Is(err, unix.EINTR) { - return err - } - } -} diff --git a/vendor/github.com/gofrs/flock/flock_windows.go b/vendor/github.com/gofrs/flock/flock_windows.go deleted file mode 100644 index dfd31e15f..000000000 --- a/vendor/github.com/gofrs/flock/flock_windows.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2024 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -//go:build windows - -package flock - -import ( - "errors" - - "golang.org/x/sys/windows" -) - -// Use of 0x00000000 for the shared lock is a guess based on some the MS Windows `LockFileEX` docs, -// which document the `LOCKFILE_EXCLUSIVE_LOCK` flag as: -// -// > The function requests an exclusive lock. Otherwise, it requests a shared lock. -// -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx -const winLockfileSharedLock = 0x00000000 - -// ErrorLockViolation is the error code returned from the Windows syscall when a lock would block, -// and you ask to fail immediately. -const ErrorLockViolation windows.Errno = 0x21 // 33 - -// Lock is a blocking call to try and take an exclusive file lock. -// It will wait until it is able to obtain the exclusive file lock. -// It's recommended that TryLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already locked, this function short-circuits and -// returns immediately assuming it can take the mutex lock. -func (f *Flock) Lock() error { - return f.lock(&f.l, windows.LOCKFILE_EXCLUSIVE_LOCK) -} - -// RLock is a blocking call to try and take a shared file lock. -// It will wait until it is able to obtain the shared file lock. -// It's recommended that TryRLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already locked, this function short-circuits and -// returns immediately assuming it can take the mutex lock. -func (f *Flock) RLock() error { - return f.lock(&f.r, winLockfileSharedLock) -} - -func (f *Flock) lock(locked *bool, flag uint32) error { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return err - } - - defer f.ensureFhState() - } - - err := windows.LockFileEx(windows.Handle(f.fh.Fd()), flag, 0, 1, 0, &windows.Overlapped{}) - if err != nil && !errors.Is(err, windows.Errno(0)) { - return err - } - - *locked = true - - return nil -} - -// Unlock is a function to unlock the file. -// This file takes a RW-mutex lock, -// so while it is running the Locked() and RLocked() functions will be blocked. -// -// This function short-circuits if we are unlocked already. -// If not, it calls UnlockFileEx() on the file and closes the file descriptor. -// It does not remove the file from disk. -// It's up to your application to do. -func (f *Flock) Unlock() error { - f.m.Lock() - defer f.m.Unlock() - - // if we aren't locked or if the lockfile instance is nil - // just return a nil error because we are unlocked - if (!f.l && !f.r) || f.fh == nil { - return nil - } - - // mark the file as unlocked - err := windows.UnlockFileEx(windows.Handle(f.fh.Fd()), 0, 1, 0, &windows.Overlapped{}) - if err != nil && !errors.Is(err, windows.Errno(0)) { - return err - } - - f.reset() - - return nil -} - -// TryLock is the preferred function for taking an exclusive file lock. -// This function does take a RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the exclusive file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being exclusive-locked. -func (f *Flock) TryLock() (bool, error) { - return f.try(&f.l, windows.LOCKFILE_EXCLUSIVE_LOCK) -} - -// TryRLock is the preferred function for taking a shared file lock. -// This function does take a RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the shared file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being shared-locked. -func (f *Flock) TryRLock() (bool, error) { - return f.try(&f.r, winLockfileSharedLock) -} - -func (f *Flock) try(locked *bool, flag uint32) (bool, error) { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return true, nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return false, err - } - - defer f.ensureFhState() - } - - err := windows.LockFileEx(windows.Handle(f.fh.Fd()), flag|windows.LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, &windows.Overlapped{}) - if err != nil && !errors.Is(err, windows.Errno(0)) { - if errors.Is(err, ErrorLockViolation) || errors.Is(err, windows.ERROR_IO_PENDING) { - return false, nil - } - - return false, err - } - - *locked = true - - return true, nil -} |
