acquireFLock attempts to acquire an exclusive file lock to serialize concurrent access. Returns the locked file handle and an unlock function, or an error if the lock cannot be acquired. The caller should read/write through the returned file to avoid Windows mandatory lock conflicts.
()
| 153 | // cannot be acquired. The caller should read/write through the returned file to |
| 154 | // avoid Windows mandatory lock conflicts. |
| 155 | func acquireFLock() (f *os.File, unlock func(), err error) { |
| 156 | lockPath, err := lockfilePath() |
| 157 | if err != nil { |
| 158 | return nil, nil, fmt.Errorf("could not determine lock path: %w", err) |
| 159 | } |
| 160 | |
| 161 | var lastErr error |
| 162 | for attempt := range lockAttempts { |
| 163 | f, unlock, err := flock.TryLock(lockPath) |
| 164 | if err == nil { |
| 165 | return f, unlock, nil |
| 166 | } |
| 167 | lastErr = err |
| 168 | |
| 169 | if !errors.Is(err, flock.ErrLocked) { |
| 170 | return nil, nil, err |
| 171 | } |
| 172 | if attempt < lockAttempts-1 { |
| 173 | time.Sleep(lockAttemptDelay) |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | return nil, nil, fmt.Errorf("could not acquire lock after %d attempts: %w", lockAttempts, lastErr) |
| 178 | } |
no test coverage detected