Update dependencies
This commit is contained in:
62
vendor/github.com/cockroachdb/pebble/vfs/mem_fs.go
generated
vendored
62
vendor/github.com/cockroachdb/pebble/vfs/mem_fs.go
generated
vendored
@@ -14,6 +14,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
@@ -63,7 +64,8 @@ func NewStrictMem() *MemFS {
|
||||
// NewMemFile returns a memory-backed File implementation. The memory-backed
|
||||
// file takes ownership of data.
|
||||
func NewMemFile(data []byte) File {
|
||||
n := &memNode{refs: 1}
|
||||
n := &memNode{}
|
||||
n.refs.Store(1)
|
||||
n.mu.data = data
|
||||
n.mu.modTime = time.Now()
|
||||
return &memFile{
|
||||
@@ -77,6 +79,11 @@ type MemFS struct {
|
||||
mu sync.Mutex
|
||||
root *memNode
|
||||
|
||||
// lockFiles holds a map of open file locks. Presence in this map indicates
|
||||
// a file lock is currently held. Keys are strings holding the path of the
|
||||
// locked file. The stored value is untyped and unused; only presence of
|
||||
// the key within the map is significant.
|
||||
lockedFiles sync.Map
|
||||
strict bool
|
||||
ignoreSyncs bool
|
||||
// Windows has peculiar semantics with respect to hard links and deleting
|
||||
@@ -217,7 +224,7 @@ func (y *MemFS) Create(fullname string) (File, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
atomic.AddInt32(&ret.n.refs, 1)
|
||||
ret.n.refs.Add(1)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -295,7 +302,7 @@ func (y *MemFS) open(fullname string, openForWrite bool) (File, error) {
|
||||
Err: oserror.ErrNotExist,
|
||||
}
|
||||
}
|
||||
atomic.AddInt32(&ret.n.refs, 1)
|
||||
ret.n.refs.Add(1)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -335,7 +342,7 @@ func (y *MemFS) Remove(fullname string) error {
|
||||
// Windows semantics. This ensures that we don't regress in the
|
||||
// ordering of operations and try to remove a file while it is
|
||||
// still open.
|
||||
if n := atomic.LoadInt32(&child.refs); n > 0 {
|
||||
if n := child.refs.Load(); n > 0 {
|
||||
return oserror.ErrInvalid
|
||||
}
|
||||
}
|
||||
@@ -456,9 +463,31 @@ func (y *MemFS) MkdirAll(dirname string, perm os.FileMode) error {
|
||||
// Lock implements FS.Lock.
|
||||
func (y *MemFS) Lock(fullname string) (io.Closer, error) {
|
||||
// FS.Lock excludes other processes, but other processes cannot see this
|
||||
// process' memory. We translate Lock into Create so that have the normal
|
||||
// detection of non-existent directory paths.
|
||||
return y.Create(fullname)
|
||||
// process' memory. However some uses (eg, Cockroach tests) may open and
|
||||
// close the same MemFS-backed database multiple times. We want mutual
|
||||
// exclusion in this case too. See cockroachdb/cockroach#110645.
|
||||
_, loaded := y.lockedFiles.Swap(fullname, nil /* the value itself is insignificant */)
|
||||
if loaded {
|
||||
// This file lock has already been acquired. On unix, this results in
|
||||
// either EACCES or EAGAIN so we mimic.
|
||||
return nil, syscall.EAGAIN
|
||||
}
|
||||
// Otherwise, we successfully acquired the lock. Locks are visible in the
|
||||
// parent directory listing, and they also must be created under an existent
|
||||
// directory. Create the path so that we have the normal detection of
|
||||
// non-existent directory paths, and make the lock visible when listing
|
||||
// directory entries.
|
||||
f, err := y.Create(fullname)
|
||||
if err != nil {
|
||||
// "Release" the lock since we failed.
|
||||
y.lockedFiles.Delete(fullname)
|
||||
return nil, err
|
||||
}
|
||||
return &memFileLock{
|
||||
y: y,
|
||||
f: f,
|
||||
fullname: fullname,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// List implements FS.List.
|
||||
@@ -525,7 +554,7 @@ func (*MemFS) GetDiskUsage(string) (DiskUsage, error) {
|
||||
type memNode struct {
|
||||
name string
|
||||
isDir bool
|
||||
refs int32
|
||||
refs atomic.Int32
|
||||
|
||||
// Mutable state.
|
||||
// - For a file: data, syncedDate, modTime: A file is only being mutated by a single goroutine,
|
||||
@@ -641,7 +670,7 @@ type memFile struct {
|
||||
var _ File = (*memFile)(nil)
|
||||
|
||||
func (f *memFile) Close() error {
|
||||
if n := atomic.AddInt32(&f.n.refs, -1); n < 0 {
|
||||
if n := f.n.refs.Add(-1); n < 0 {
|
||||
panic(fmt.Sprintf("pebble: close of unopened file: %d", n))
|
||||
}
|
||||
f.n = nil
|
||||
@@ -786,3 +815,18 @@ func (f *memFile) Fd() uintptr {
|
||||
func (f *memFile) Flush() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type memFileLock struct {
|
||||
y *MemFS
|
||||
f File
|
||||
fullname string
|
||||
}
|
||||
|
||||
func (l *memFileLock) Close() error {
|
||||
if l.y == nil {
|
||||
return nil
|
||||
}
|
||||
l.y.lockedFiles.Delete(l.fullname)
|
||||
l.y = nil
|
||||
return l.f.Close()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user