Repository navigation
unlock(remove = TRUE): delete the lock file on release, safely - #1
Merged
Merged
Conversation
lock() now checks (fstat vs stat: device and inode) that the file it locked is still the one at `path`, and starts over if not; ESTALE (NFS) also starts over. unlock(remove = TRUE) deletes the file just before releasing an exclusive lock's last reference. Without the check, deleting would let a waiter on the old file and a newcomer on a new file both hold "the" lock. Windows ignores `remove`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # NEWS.md # src/filelock-unix.c # tests/testthat/test.R
main now carries r-lib#58 instead of a2fe838. The retry loop in filelock_lock() (start over when the locked file is no longer the one at `path`, or on ESTALE) now wraps r-lib#58's code, including its R_UnwindProtect() around the wait, so a failed or interrupted attempt still closes the file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oFSqD7YBJZdkFfStooVtz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lock files are never deleted today, so a cache that locks one file per entry ends up with hundreds of thousands of empty files that are not in use. This adds an option to delete a lock file when its lock is released, without the race that naive deletion causes, so lock files exist only while in use.
Affects: nothing unless
unlock(remove = TRUE)is used;lock()also now re-checks the file it locked, which always passes when no one deletes lock files.Technical details
Deleting a lock file while another process waits on it is unsafe: the waiter later gets its lock on the deleted file, while a newcomer creates and locks a new file at the same path, so both "hold" the lock. Now:
filelock_lock()(src/filelock-unix.c): after acquiring,filelock__same_file()comparesfstat()of the open file withstat()of the path (device and inode). If they differ, or the path is gone, it closes and starts over (the timeout restarts).ESTALEfromfcntl()(NFS, file deleted by its holder) also starts over. The loop wraps the code of Close the lock file when lock() fails to get the lock r-lib/filelock#58, now onmain, including itsR_UnwindProtect()around the wait, so every failed or interrupted attempt still closes the file.filelock_unlock(lock, remove): withremove = TRUE, an exclusive lock's last referenceunlink()s the file beforeclose(). Shared locks and nested references keep it. A crash leaves the file; the nextunlock(remove = TRUE)on it deletes it.removeis ignored (a file other processes have open cannot be deleted there).Tests:
removedeletes only on the last exclusive release; a waiter whose file is deleted ends up holding the new file at the path (fails when the waiter runs the old code). With r-lib#58's leak tests, 57 tests pass on Linux. Stress test outside the suite: 8 processes × 300 increments of a shared counter under the lock, deleting on every release: 2400/2400 in 3/3 runs; with the same-file check disabled the counter file ends up empty (two processes in the critical section) in 3/3 runs. Not built or tested on Windows or macOS. Version 1.0.3.9002, so reproducible can detect it.🤖 Generated with Claude Code
https://claude.ai/code/session_011oFSqD7YBJZdkFfStooVtz