doc/news.texi | 8 ++++++++ main.go | 9 +++++++-- ood.go | 18 ++++++++++++++---- run.go | 18 +++++++++++++----- usage.go | 2 +- diff --git a/doc/news.texi b/doc/news.texi index 4c971fe7fd20ee6d487aa93bbefdfdd819a72871dab8f623188a4e04fd0677cc..08db9b450788573cd8f9301ad81fc1bb302b937c7057b624756f0170f05251a7 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 5c3030d09d3626a1863b63989b2f21cb8735a1a28bf522c0da9bdb2cf2d6b68e..707a1f0ace625f1d32aec36154f65a8507350b80f7f74f72c9414a2805b1b389 100644 --- a/main.go +++ b/main.go @@ -227,7 +227,11 @@ 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 @@ tgtsRaw, err := ioutil.ReadAll(bufio.NewReader(fd)) 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 d401c0ca34a75d06a6da7e4bde886359b176bb446df19cb80aa49c932b2b7acc..1ea43d22df97f002cd9a212535199cc2326a80a3b1c077dca50b5f33684746e7 100644 --- a/ood.go +++ b/ood.go @@ -250,7 +250,11 @@ if !ood { 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 @@ } 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 @@ } 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 5d30722d3a5d07ad33406debf14884067af7eb4229556b4217a6eb13fb259f51..eab2bd8363d1bd12d6a9a4b907f0d5c55315aa65722fe1c850148f3aa1acc5a6 100644 --- a/run.go +++ b/run.go @@ -198,9 +198,14 @@ ) 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 @@ } 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 @@ } 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 6befd5c6ba46ed1cc12dca6298065478abdef2e232d4a979e0e40414de866720..c54376bfce6add3403dcc8006c649b382e5e00001945386a2a1a5137ce0feb7d 100644 --- a/usage.go +++ b/usage.go @@ -24,7 +24,7 @@ "os" ) 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