Skip to content

Commit

Permalink
Fix windows WithDirLock to exclusive lock
Browse files Browse the repository at this point in the history
We use LOCKFILE_FAIL_IMMEDIATELY, creating a shared lock that fail
immediately if the lock cannot be acquired. This does not match the
behavior of the unix version and does not make sense.

Using now LOCKFILE_EXCLUSIVE_LOCK to acquire exclusive lock blocking
until the lock can be acquired.

Add constants for the flags and add comments for the argument names to
prevent future errors.

Signed-off-by: Nir Soffer <[email protected]>
  • Loading branch information
nirs committed Oct 13, 2024
1 parent 86a5f5f commit a64eba6
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions pkg/lockutil/lockutil_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,37 @@ var (
procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
)

const (
// see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
LOCKFILE_EXCLUSIVE_LOCK = 0x00000002
LOCKFILE_FAIL_IMMEDIATELY = 0x00000001
)

func WithDirLock(dir string, fn func() error) error {
dirFile, err := os.OpenFile(dir+".lock", os.O_CREATE, 0o644)
if err != nil {
return err
}
defer dirFile.Close()
// see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
// 1 lock immediately
if err := lockFileEx(syscall.Handle(dirFile.Fd()), 1, 0, 1, 0, &syscall.Overlapped{}); err != nil {
if err := lockFileEx(
syscall.Handle(dirFile.Fd()), // hFile
LOCKFILE_EXCLUSIVE_LOCK, // dwFlags
0, // dwReserved
1, // nNumberOfBytesToLockLow
0, // nNumberOfBytesToLockHigh
&syscall.Overlapped{}, // lpOverlapped
); err != nil {
return fmt.Errorf("failed to lock %q: %w", dir, err)
}

defer func() {
if err := unlockFileEx(syscall.Handle(dirFile.Fd()), 0, 1, 0, &syscall.Overlapped{}); err != nil {
if err := unlockFileEx(
syscall.Handle(dirFile.Fd()), // hFile
0, // dwReserved
1, // nNumberOfBytesToLockLow
0, // nNumberOfBytesToLockHigh
&syscall.Overlapped{}, // lpOverlapped
); err != nil {
logrus.WithError(err).Errorf("failed to unlock %q", dir)
}
}()
Expand Down

0 comments on commit a64eba6

Please sign in to comment.