Skip to content

Commit

Permalink
refactor: factorization of the reset (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez authored Jul 2, 2024
1 parent 1113ec8 commit c541671
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 28 deletions.
9 changes: 9 additions & 0 deletions flock.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,12 @@ func (f *Flock) ensureFhState() {

f.fh = nil
}

func (f *Flock) reset() {
f.l = false
f.r = false

_ = f.fh.Close()

f.fh = nil
}
23 changes: 11 additions & 12 deletions flock_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ func (f *Flock) lock(locked *bool, flag int) error {
defer f.ensureFhState()
}

if err := syscall.Flock(int(f.fh.Fd()), flag); err != nil {
err := syscall.Flock(int(f.fh.Fd()), flag)
if err != nil {
shouldRetry, reopenErr := f.reopenFDOnError(err)
if reopenErr != nil {
return reopenErr
Expand All @@ -66,7 +67,8 @@ func (f *Flock) lock(locked *bool, flag int) error {
return err
}

if err = syscall.Flock(int(f.fh.Fd()), flag); err != nil {
err = syscall.Flock(int(f.fh.Fd()), flag)
if err != nil {
return err
}
}
Expand Down Expand Up @@ -99,15 +101,12 @@ func (f *Flock) Unlock() error {
}

// Mark the file as unlocked.
if err := syscall.Flock(int(f.fh.Fd()), syscall.LOCK_UN); err != nil {
err := syscall.Flock(int(f.fh.Fd()), syscall.LOCK_UN)
if err != nil {
return err
}

_ = f.fh.Close()

f.l = false
f.r = false
f.fh = nil
f.reset()

return nil
}
Expand Down Expand Up @@ -167,7 +166,8 @@ retry:
}

if !retried {
if shouldRetry, reopenErr := f.reopenFDOnError(err); reopenErr != nil {
shouldRetry, reopenErr := f.reopenFDOnError(err)
if reopenErr != nil {
return false, reopenErr
} else if shouldRetry {
retried = true
Expand All @@ -180,9 +180,8 @@ retry:

// 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().
// > Since Linux 3.4 (commit 55725513)
// > Probably NFSv4 where flock() is emulated by fcntl().
func (f *Flock) reopenFDOnError(err error) (bool, error) {
if !errors.Is(err, syscall.EIO) && !errors.Is(err, syscall.EBADF) {
return false, nil
Expand Down
20 changes: 10 additions & 10 deletions flock_unix_variants.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ func (f *Flock) lock(locked *bool, flag lockType) error {
defer f.ensureFhState()
}

if _, err := f.doLock(waitLock, flag, true); err != nil {
_, err := f.doLock(waitLock, flag, true)
if err != nil {
return err
}

Expand Down Expand Up @@ -137,16 +138,19 @@ func (f *Flock) doLock(cmd cmdType, lt lockType, blocking bool) (bool, error) {

l := locks[ino]

if l.owner == f {
switch {
case l.owner == f:
// This file already owns the lock, but the call may change its lock type.
} else if l.owner == nil {
case l.owner == nil:
// No owner: it's ours now.
l.owner = f
} else if !blocking {

case !blocking:
// Already owned: cannot take the lock.
mu.Unlock()
return false, nil
} else {

default:
// Already owned: add a channel to wait on.
wait = make(chan *Flock)
l.queue = append(l.queue, wait)
Expand Down Expand Up @@ -188,11 +192,7 @@ func (f *Flock) Unlock() error {
return err
}

_ = f.fh.Close()

f.l = false
f.r = false
f.fh = nil
f.reset()

return nil
}
Expand Down
9 changes: 3 additions & 6 deletions flock_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package flock

import (
"errors"
"syscall"
)

Expand Down Expand Up @@ -85,11 +86,7 @@ func (f *Flock) Unlock() error {
return errNo
}

_ = f.fh.Close()

f.l = false
f.r = false
f.fh = nil
f.reset()

return nil
}
Expand Down Expand Up @@ -137,7 +134,7 @@ func (f *Flock) try(locked *bool, flag uint32) (bool, error) {

_, errNo := lockFileEx(syscall.Handle(f.fh.Fd()), flag|winLockfileFailImmediately, 0, 1, 0, &syscall.Overlapped{})
if errNo > 0 {
if errNo == ErrorLockViolation || errNo == syscall.ERROR_IO_PENDING {
if errors.Is(errNo, ErrorLockViolation) || errors.Is(errNo, syscall.ERROR_IO_PENDING) {
return false, nil
}

Expand Down

0 comments on commit c541671

Please sign in to comment.