diff options
Diffstat (limited to 'internal/stats/stats.go')
| -rw-r--r-- | internal/stats/stats.go | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/internal/stats/stats.go b/internal/stats/stats.go index 7fa61b0..95981c5 100644 --- a/internal/stats/stats.go +++ b/internal/stats/stats.go @@ -151,18 +151,24 @@ func Update(ctx context.Context, provider, model string, sentBytes, recvBytes in return nil } +// acquireFileLock spins on tryLockFile until it succeeds, the context is +// cancelled, or an unexpected error occurs. A single timer is reused across +// retries to avoid leaking timers/channels on every loop iteration. func acquireFileLock(ctx context.Context, f *os.File) (func() error, error) { fd := f.Fd() + retryTimer := time.NewTimer(5 * time.Millisecond) + defer retryTimer.Stop() for { err := tryLockFile(fd) if err == nil { return func() error { return unlockFile(fd) }, nil } if errors.Is(err, errLockWouldBlock) { + retryTimer.Reset(5 * time.Millisecond) select { case <-ctx.Done(): return nil, ctx.Err() - case <-time.After(5 * time.Millisecond): + case <-retryTimer.C: } continue } |
