mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 05:59:14 +00:00
Towards lock timeouts.
This commit is contained in:
47
vfs_unix.go
47
vfs_unix.go
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user