Towards lock timeouts.

This commit is contained in:
Nuno Cruces
2023-03-15 13:31:18 +00:00
parent 77088962f5
commit 6fc0afcd12
2 changed files with 34 additions and 17 deletions

View File

@@ -6,6 +6,7 @@ import (
"io/fs"
"os"
"runtime"
"time"
"golang.org/x/sys/unix"
)
@@ -72,7 +73,7 @@ func (vfsOSMethods) ReleaseLock(file *os.File, _ vfsLockState) xErrorCode {
}
func (vfsOSMethods) unlock(file *os.File, start, len int64) xErrorCode {
err := vfsOS.fcntlSetLock(file, &unix.Flock_t{
err := vfsOS.fcntlSetLock(file, unix.Flock_t{
Type: unix.F_UNLCK,
Start: start,
Len: len,
@@ -84,7 +85,7 @@ func (vfsOSMethods) unlock(file *os.File, start, len int64) xErrorCode {
}
func (vfsOSMethods) readLock(file *os.File, start, len int64) xErrorCode {
return vfsOS.lockErrorCode(vfsOS.fcntlSetLock(file, &unix.Flock_t{
return vfsOS.lockErrorCode(vfsOS.fcntlSetLock(file, unix.Flock_t{
Type: unix.F_RDLCK,
Start: start,
Len: len,
@@ -92,7 +93,8 @@ func (vfsOSMethods) readLock(file *os.File, start, len int64) xErrorCode {
}
func (vfsOSMethods) writeLock(file *os.File, start, len int64) xErrorCode {
return vfsOS.lockErrorCode(vfsOS.fcntlSetLock(file, &unix.Flock_t{
// TODO: implement timeouts.
return vfsOS.lockErrorCode(vfsOS.fcntlSetLock(file, unix.Flock_t{
Type: unix.F_WRLCK,
Start: start,
Len: len,
@@ -115,36 +117,47 @@ func (vfsOSMethods) fcntlGetLock(file *os.File, lock *unix.Flock_t) error {
var F_OFD_GETLK int
switch runtime.GOOS {
case "linux":
// https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/fcntl.h
F_OFD_GETLK = 36
F_OFD_GETLK = 36 // https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/fcntl.h
case "darwin":
// https://github.com/apple/darwin-xnu/blob/main/bsd/sys/fcntl.h
F_OFD_GETLK = 92
F_OFD_GETLK = 92 // https://github.com/apple/darwin-xnu/blob/main/bsd/sys/fcntl.h
case "illumos":
// https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/sys/fcntl.h
F_OFD_GETLK = 47
F_OFD_GETLK = 47 // https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/sys/fcntl.h
default:
return notImplErr
}
return unix.FcntlFlock(file.Fd(), F_OFD_GETLK, lock)
}
func (vfsOSMethods) fcntlSetLock(file *os.File, lock *unix.Flock_t) error {
func (vfsOSMethods) fcntlSetLock(file *os.File, lock unix.Flock_t) error {
var F_OFD_SETLK int
switch runtime.GOOS {
case "linux":
// https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/fcntl.h
F_OFD_SETLK = 37
F_OFD_SETLK = 37 // https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/fcntl.h
case "darwin":
// https://github.com/apple/darwin-xnu/blob/main/bsd/sys/fcntl.h
F_OFD_SETLK = 90
F_OFD_SETLK = 90 // https://github.com/apple/darwin-xnu/blob/main/bsd/sys/fcntl.h
case "illumos":
// https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/sys/fcntl.h
F_OFD_SETLK = 48
F_OFD_SETLK = 48 // https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/sys/fcntl.h
default:
return notImplErr
}
return unix.FcntlFlock(file.Fd(), F_OFD_SETLK, lock)
return unix.FcntlFlock(file.Fd(), F_OFD_SETLK, &lock)
}
func (vfsOSMethods) fcntlSetLockTimeout(timeout time.Duration, file *os.File, lock unix.Flock_t) error {
if runtime.GOOS != "darwin" || timeout == 0 {
return vfsOS.fcntlSetLock(file, lock)
}
const F_OFD_SETLKWTIMEOUT = 93 // https://github.com/apple/darwin-xnu/blob/main/bsd/sys/fcntl.h
flocktimeout := &struct {
unix.Flock_t
unix.Timespec
}{
Flock_t: lock,
Timespec: unix.NsecToTimespec(int64(timeout / time.Nanosecond)),
}
return unix.FcntlFlock(file.Fd(), F_OFD_SETLKWTIMEOUT, &flocktimeout.Flock_t)
}
func (vfsOSMethods) lockErrorCode(err error, def xErrorCode) xErrorCode {

View File

@@ -136,6 +136,9 @@ func (vfsOSMethods) readLock(file *os.File, start, len uint32) xErrorCode {
}
func (vfsOSMethods) writeLock(file *os.File, start, len uint32) xErrorCode {
// TODO: implement timeouts.
// https://devblogs.microsoft.com/oldnewthing/20140905-00/?p=63
// https://learn.microsoft.com/en-ie/windows/win32/api/winbase/nf-winbase-reopenfile
return vfsOS.lockErrorCode(windows.LockFileEx(windows.Handle(file.Fd()),
windows.LOCKFILE_FAIL_IMMEDIATELY|windows.LOCKFILE_EXCLUSIVE_LOCK,
0, len, 0, &windows.Overlapped{Offset: start}),
@@ -143,6 +146,7 @@ func (vfsOSMethods) writeLock(file *os.File, start, len uint32) xErrorCode {
}
func (vfsOSMethods) checkLock(file *os.File, start, len uint32) (bool, xErrorCode) {
// TODO: report errors.
rc := vfsOS.readLock(file, start, len)
if rc == _OK {
vfsOS.unlock(file, start, len)