Skip to content

Commit 52a6972

Browse files
committed
ignore flock errors due to contention
1 parent 555110f commit 52a6972

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

extensions/internal/lock/lock.go

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"fmt"
1010
"os"
1111
"path/filepath"
12+
"runtime"
13+
"syscall"
1214
"time"
1315

1416
"github.com/AzureAD/microsoft-authentication-extensions-for-go/extensions/internal/flock"
@@ -51,15 +53,21 @@ func (l *Lock) Lock(ctx context.Context) error {
5153
ctx, cancel = context.WithTimeout(ctx, timeout)
5254
defer cancel()
5355
}
54-
locked, err := l.f.TryLockContext(ctx, l.retryDelay)
55-
if err != nil {
56-
return err
57-
}
58-
if locked {
59-
_, _ = l.f.Fh().WriteString(fmt.Sprintf("{%d} {%s}", os.Getpid(), os.Args[0]))
60-
return nil
56+
for {
57+
// flock opens the file before locking it and returns errors due to an existing
58+
// lock or one acquired by another process after this process has opened the
59+
// file. We ignore some errors here because in such cases we want to retry until
60+
// the deadline.
61+
locked, err := l.f.TryLockContext(ctx, l.retryDelay)
62+
if err != nil {
63+
if !(errors.Is(err, os.ErrPermission) || isWindowsSharingViolation(err)) {
64+
return err
65+
}
66+
} else if locked {
67+
_, _ = l.f.Fh().WriteString(fmt.Sprintf("{%d} {%s}", os.Getpid(), os.Args[0]))
68+
return nil
69+
}
6170
}
62-
return errors.New("couldn't acquire file lock")
6371
}
6472

6573
// Unlock releases the lock and deletes the lock file.
@@ -68,8 +76,13 @@ func (l *Lock) Unlock() error {
6876
if err == nil {
6977
err = os.Remove(l.f.Path())
7078
}
71-
if errors.Is(err, os.ErrNotExist) {
79+
// ignore errors caused by another process deleting the file or locking between the above Unlock and Remove
80+
if errors.Is(err, os.ErrNotExist) || errors.Is(err, os.ErrPermission) || isWindowsSharingViolation(err) {
7281
return nil
7382
}
7483
return err
7584
}
85+
86+
func isWindowsSharingViolation(err error) bool {
87+
return runtime.GOOS == "windows" && errors.Is(err, syscall.Errno(32))
88+
}

0 commit comments

Comments
 (0)