Skip to content

Commit

Permalink
Merge pull request #52 from jwatson-gcu/bugs/fix-trylock-aix
Browse files Browse the repository at this point in the history
Fix issue caused by calling F_SETLKW instead of F_SETLK
  • Loading branch information
theckman committed Jun 26, 2021
2 parents 75ec202 + 2258078 commit 6f010d1
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions flock_aix.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ const (
writeLock lockType = unix.F_WRLCK
)

type cmdType int

const (
tryLock cmdType = unix.F_SETLK
waitLock cmdType = unix.F_SETLKW
)

type inode = uint64

type inodeLock struct {
Expand Down Expand Up @@ -90,15 +97,15 @@ func (f *Flock) lock(locked *bool, flag lockType) error {
defer f.ensureFhState()
}

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

*locked = true
return nil
}

func (f *Flock) doLock(lt lockType, blocking bool) (bool, error) {
func (f *Flock) doLock(cmd cmdType, lt lockType, blocking bool) (bool, error) {
// POSIX locks apply per inode and process, and the lock for an inode is
// released when *any* descriptor for that inode is closed. So we need to
// synchronize access to each inode internally, and must serialize lock and
Expand Down Expand Up @@ -143,10 +150,13 @@ func (f *Flock) doLock(lt lockType, blocking bool) (bool, error) {
wait <- f
}

err = setlkw(f.fh.Fd(), lt)
err = setlkw(f.fh.Fd(), cmd, lt)

if err != nil {
f.doUnlock()
if cmd == tryLock && err == unix.EACCES {
return false, nil
}
return false, err
}

Expand Down Expand Up @@ -186,7 +196,7 @@ func (f *Flock) doUnlock() (err error) {
mu.Unlock()

if owner == f {
err = setlkw(f.fh.Fd(), unix.F_UNLCK)
err = setlkw(f.fh.Fd(), waitLock, unix.F_UNLCK)
}

mu.Lock()
Expand Down Expand Up @@ -246,7 +256,7 @@ func (f *Flock) try(locked *bool, flag lockType) (bool, error) {
defer f.ensureFhState()
}

haslock, err := f.doLock(flag, false)
haslock, err := f.doLock(tryLock, flag, false)
if err != nil {
return false, err
}
Expand All @@ -255,10 +265,10 @@ func (f *Flock) try(locked *bool, flag lockType) (bool, error) {
return haslock, nil
}

// setlkw calls FcntlFlock with F_SETLKW for the entire file indicated by fd.
func setlkw(fd uintptr, lt lockType) error {
// setlkw calls FcntlFlock with cmd for the entire file indicated by fd.
func setlkw(fd uintptr, cmd cmdType, lt lockType) error {
for {
err := unix.FcntlFlock(fd, unix.F_SETLKW, &unix.Flock_t{
err := unix.FcntlFlock(fd, int(cmd), &unix.Flock_t{
Type: int16(lt),
Whence: io.SeekStart,
Start: 0,
Expand Down

0 comments on commit 6f010d1

Please sign in to comment.