From 3b08d02a8391b1cb49fd97f6d22800332d44d70c Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Thu, 23 Mar 2023 01:07:38 +0000 Subject: [PATCH] Lock refactoring. --- vfs_os_darwin.go | 30 +++++++++++------------------- vfs_os_linux.go | 29 ++++++++--------------------- vfs_os_other.go | 24 ++++++++---------------- vfs_os_windows.go | 8 +++++--- 4 files changed, 32 insertions(+), 59 deletions(-) diff --git a/vfs_os_darwin.go b/vfs_os_darwin.go index 6cd0c4b..1c3bcc7 100644 --- a/vfs_os_darwin.go +++ b/vfs_os_darwin.go @@ -24,10 +24,10 @@ type flocktimeout_t struct { } func (vfsOSMethods) Sync(file *os.File, fullsync, dataonly bool) error { - if !fullsync { - return unix.Fsync(int(file.Fd())) + if fullsync { + return file.Sync() } - return file.Sync() + return unix.Fsync(int(file.Fd())) } func (vfsOSMethods) Allocate(file *os.File, size int64) error { @@ -69,9 +69,9 @@ func (vfsOSMethods) unlock(file *os.File, start, len int64) xErrorCode { return _OK } -func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { +func (vfsOSMethods) lock(file *os.File, typ int16, start, len int64, timeout time.Duration, def xErrorCode) xErrorCode { lock := flocktimeout_t{fl: unix.Flock_t{ - Type: unix.F_RDLCK, + Type: typ, Start: start, Len: len, }} @@ -82,23 +82,15 @@ func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Durat lock.timeout = unix.NsecToTimespec(int64(timeout / time.Nanosecond)) err = unix.FcntlFlock(file.Fd(), _F_OFD_SETLKWTIMEOUT, &lock.fl) } - return vfsOS.lockErrorCode(err, IOERR_RDLOCK) + return vfsOS.lockErrorCode(err, def) +} + +func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { + return vfsOS.lock(file, unix.F_RDLCK, start, len, timeout, IOERR_RDLOCK) } func (vfsOSMethods) writeLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { - lock := flocktimeout_t{fl: unix.Flock_t{ - Type: unix.F_WRLCK, - Start: start, - Len: len, - }} - var err error - if timeout == 0 { - err = unix.FcntlFlock(file.Fd(), _F_OFD_SETLK, &lock.fl) - } else { - lock.timeout = unix.NsecToTimespec(int64(timeout / time.Nanosecond)) - err = unix.FcntlFlock(file.Fd(), _F_OFD_SETLKWTIMEOUT, &lock.fl) - } - return vfsOS.lockErrorCode(err, IOERR_LOCK) + return vfsOS.lock(file, unix.F_WRLCK, start, len, timeout, IOERR_LOCK) } func (vfsOSMethods) checkLock(file *os.File, start, len int64) (bool, xErrorCode) { diff --git a/vfs_os_linux.go b/vfs_os_linux.go index e19ab74..9f06408 100644 --- a/vfs_os_linux.go +++ b/vfs_os_linux.go @@ -37,9 +37,9 @@ func (vfsOSMethods) unlock(file *os.File, start, len int64) xErrorCode { return _OK } -func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { +func (vfsOSMethods) lock(file *os.File, typ int16, start, len int64, timeout time.Duration, def xErrorCode) xErrorCode { lock := unix.Flock_t{ - Type: unix.F_RDLCK, + Type: typ, Start: start, Len: len, } @@ -55,28 +55,15 @@ func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Durat timeout -= time.Millisecond time.Sleep(time.Millisecond) } - return vfsOS.lockErrorCode(err, IOERR_RDLOCK) + return vfsOS.lockErrorCode(err, def) +} + +func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { + return vfsOS.lock(file, unix.F_RDLCK, start, len, timeout, IOERR_RDLOCK) } func (vfsOSMethods) writeLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { - lock := unix.Flock_t{ - Type: unix.F_WRLCK, - Start: start, - Len: len, - } - var err error - for { - err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &lock) - if errno, _ := err.(unix.Errno); errno != unix.EAGAIN { - break - } - if timeout < time.Millisecond { - break - } - timeout -= time.Millisecond - time.Sleep(time.Millisecond) - } - return vfsOS.lockErrorCode(err, IOERR_RDLOCK) + return vfsOS.lock(file, unix.F_WRLCK, start, len, timeout, IOERR_LOCK) } func (vfsOSMethods) checkLock(file *os.File, start, len int64) (bool, xErrorCode) { diff --git a/vfs_os_other.go b/vfs_os_other.go index 6b57ae2..23e52ca 100644 --- a/vfs_os_other.go +++ b/vfs_os_other.go @@ -35,10 +35,10 @@ func (vfsOSMethods) unlock(file *os.File, start, len int64) xErrorCode { return _OK } -func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { +func (vfsOSMethods) lock(file *os.File, how int, timeout time.Duration, def xErrorCode) xErrorCode { var err error for { - err = unix.Flock(int(file.Fd()), unix.LOCK_SH|unix.LOCK_NB) + err = unix.Flock(int(file.Fd()), how) if errno, _ := err.(unix.Errno); errno != unix.EAGAIN { break } @@ -48,23 +48,15 @@ func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Durat timeout -= time.Millisecond time.Sleep(time.Millisecond) } - return vfsOS.lockErrorCode(err, IOERR_RDLOCK) + return vfsOS.lockErrorCode(err, def) +} + +func (vfsOSMethods) readLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { + return vfsOS.lock(file, unix.LOCK_SH|unix.LOCK_NB, timeout, IOERR_RDLOCK) } func (vfsOSMethods) writeLock(file *os.File, start, len int64, timeout time.Duration) xErrorCode { - var err error - for { - err = unix.Flock(int(file.Fd()), unix.LOCK_EX|unix.LOCK_NB) - if errno, _ := err.(unix.Errno); errno != unix.EAGAIN { - break - } - if timeout < time.Millisecond { - break - } - timeout -= time.Millisecond - time.Sleep(time.Millisecond) - } - return vfsOS.lockErrorCode(err, IOERR_RDLOCK) + return vfsOS.lock(file, unix.LOCK_EX|unix.LOCK_NB, timeout, IOERR_LOCK) } func (vfsOSMethods) checkLock(file *os.File, start, len int64) (bool, xErrorCode) { diff --git a/vfs_os_windows.go b/vfs_os_windows.go index 0699d13..75df4fd 100644 --- a/vfs_os_windows.go +++ b/vfs_os_windows.go @@ -131,18 +131,20 @@ func (vfsOSMethods) unlock(file *os.File, start, len uint32) xErrorCode { } func (vfsOSMethods) lock(file *os.File, flags, start, len uint32, timeout time.Duration, def xErrorCode) xErrorCode { + var err error for { - err := windows.LockFileEx(windows.Handle(file.Fd()), flags, + err = windows.LockFileEx(windows.Handle(file.Fd()), flags, 0, len, 0, &windows.Overlapped{Offset: start}) if errno, _ := err.(windows.Errno); errno != windows.ERROR_LOCK_VIOLATION { - return vfsOS.lockErrorCode(err, def) + break } if timeout < time.Millisecond { - return vfsOS.lockErrorCode(err, def) + break } timeout -= time.Millisecond time.Sleep(time.Millisecond) } + return vfsOS.lockErrorCode(err, def) } func (vfsOSMethods) readLock(file *os.File, start, len uint32, timeout time.Duration) xErrorCode {