From f0f007ed9bb046289965d2a7e64f215e4a50a441 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Mon, 10 Jan 2022 23:40:16 +0300 Subject: [PATCH] Replace flock() with fcntl() locks --- doc/news.texi | 8 ++++++++ main.go | 9 +++++++-- ood.go | 18 ++++++++++++++---- run.go | 18 +++++++++++++----- usage.go | 2 +- 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/doc/news.texi b/doc/news.texi index ec4da6f..475fe98 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -1,6 +1,14 @@ @node News @unnumbered News +@anchor{Release 1_22_0} +@section Release 1.22.0 +@itemize +@item + @code{flock} locks replaced with POSIX @code{fcntl} ones. + They could be more portable. +@end itemize + @anchor{Release 1_21_0} @section Release 1.21.0 @itemize diff --git a/main.go b/main.go index f87bdac..5bb158b 100644 --- a/main.go +++ b/main.go @@ -227,7 +227,11 @@ func main() { if v := os.Getenv(EnvOODTgtsFd); v != "" { fd := mustParseFd(v, EnvOODTgtsFd) fdLock := mustParseFd(v, EnvOODTgtsLockFd) - if err = unix.Flock(int(fdLock.Fd()), unix.LOCK_EX); err != nil { + flock := unix.Flock_t{ + Type: unix.F_WRLCK, + Whence: io.SeekStart, + } + if err = unix.FcntlFlock(fdLock.Fd(), unix.F_SETLKW, &flock); err != nil { log.Fatalln(err) } if _, err = fd.Seek(0, io.SeekStart); err != nil { @@ -237,7 +241,8 @@ func main() { if err != nil { log.Fatalln(err) } - if err = unix.Flock(int(fdLock.Fd()), unix.LOCK_UN); err != nil { + flock.Type = unix.F_UNLCK + if err = unix.FcntlFlock(fdLock.Fd(), unix.F_SETLK, &flock); err != nil { log.Fatalln(err) } OODTgts = map[string]struct{}{} diff --git a/ood.go b/ood.go index e216595..39c265c 100644 --- a/ood.go +++ b/ood.go @@ -250,7 +250,11 @@ func isOODWithTrace( return ood, err } RecordOODTgt: - if err = unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_EX); err != nil { + flock := unix.Flock_t{ + Type: unix.F_WRLCK, + Whence: io.SeekStart, + } + if err = unix.FcntlFlock(FdOODTgtsLock.Fd(), unix.F_SETLKW, &flock); err != nil { log.Fatalln(err) } if _, err = FdOODTgts.Seek(0, io.SeekEnd); err != nil { @@ -259,7 +263,8 @@ RecordOODTgt: if _, err := FdOODTgts.WriteString(p + "\x00"); err != nil { log.Fatalln(err) } - if err = unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_UN); err != nil { + flock.Type = unix.F_UNLCK + if err = unix.FcntlFlock(FdOODTgtsLock.Fd(), unix.F_SETLK, &flock); err != nil { log.Fatalln(err) } return true, nil @@ -267,13 +272,18 @@ RecordOODTgt: func oodTgtsClear() { var err error - if err = unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_EX); err != nil { + flock := unix.Flock_t{ + Type: unix.F_WRLCK, + Whence: io.SeekStart, + } + if err = unix.FcntlFlock(FdOODTgtsLock.Fd(), unix.F_SETLKW, &flock); err != nil { log.Fatalln(err) } if err = FdOODTgts.Truncate(0); err != nil { log.Fatalln(err) } - if err = unix.Flock(int(FdOODTgtsLock.Fd()), unix.LOCK_UN); err != nil { + flock.Type = unix.F_UNLCK + if err = unix.FcntlFlock(FdOODTgtsLock.Fd(), unix.F_SETLK, &flock); err != nil { log.Fatalln(err) } } diff --git a/run.go b/run.go index a3740c2..6366f4a 100644 --- a/run.go +++ b/run.go @@ -198,9 +198,14 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { if err != nil { return TgtError{tgtOrig, err} } + flock := unix.Flock_t{ + Type: unix.F_WRLCK, + Whence: io.SeekStart, + } lockRelease := func() { tracef(CLock, "LOCK_UN: %s", fdLock.Name()) - if err := unix.Flock(int(fdLock.Fd()), unix.LOCK_UN); err != nil { + flock.Type = unix.F_UNLCK + if err := unix.FcntlFlock(fdLock.Fd(), unix.F_SETLK, &flock); err != nil { log.Fatalln(err) } fdLock.Close() @@ -208,13 +213,16 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { tracef(CLock, "LOCK_NB: %s", fdLock.Name()) // Waiting for job completion, already taken by someone else - if err = unix.Flock(int(fdLock.Fd()), unix.LOCK_EX|unix.LOCK_NB); err != nil { - if uintptr(err.(syscall.Errno)) != uintptr(unix.EWOULDBLOCK) { + if err = unix.FcntlFlock(fdLock.Fd(), unix.F_SETLK, &flock); err != nil { + if uintptr(err.(syscall.Errno)) != uintptr(unix.EAGAIN) { fdLock.Close() return TgtError{tgtOrig, err} } Jobs.Add(1) - tracef(CDebug, "waiting: %s", tgtOrig) + if err = unix.FcntlFlock(fdLock.Fd(), unix.F_GETLK, &flock); err != nil { + log.Fatalln(err) + } + tracef(CDebug, "waiting: %s (pid=%d)", tgtOrig, flock.Pid) if FdStatus != nil { if _, err = FdStatus.Write([]byte{StatusWait}); err != nil { log.Fatalln(err) @@ -223,7 +231,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { go func() { defer Jobs.Done() tracef(CLock, "LOCK_EX: %s", fdLock.Name()) - if err := unix.Flock(int(fdLock.Fd()), unix.LOCK_EX); err != nil { + if err := unix.FcntlFlock(fdLock.Fd(), unix.F_SETLKW, &flock); err != nil { log.Fatalln(err) } lockRelease() diff --git a/usage.go b/usage.go index c13c033..9d929e3 100644 --- a/usage.go +++ b/usage.go @@ -24,7 +24,7 @@ import ( ) const ( - Version = "1.21.0" + Version = "1.22.0" Warranty = `Copyright (C) 2020-2022 Sergey Matveev This program is free software: you can redistribute it and/or modify -- 2.44.0