clawhdf5: a dropped FileEditor releases its lock at once
FileEditor's flock belongs to the open file description. When another thread forks to spawn a process, the child shares the locked descriptor until it execs, so a reopen right after the drop could be refused with Error::Locked (a one-off failure of edit_interop::editor_locks_the_file in a parallel test run). Drop now unlocks before closing, which releases the lock for every descriptor sharing it. Reproducer edit_tests::drop_releases_the_lock_while_other_threads_spawn_processes (4 threads running `true`, 2000 open/drop rounds): 1483 of 2000 reopens refused before, 0 in 30 runs after (tank). An OFD lock would not help: it is inherited across fork the same way and does not conflict with libhdf5's flock. The agent store's lock file unlocks on drop too. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -448,6 +448,35 @@ Newest first. "Before any release" means no tagged release (v2.7.0 and
|
||||
earlier) contains the bug. Full detail is in `CHANGELOG.md` under the date
|
||||
given.
|
||||
|
||||
## A dropped `FileEditor` could keep its file locked for a moment
|
||||
|
||||
**Status:** fixed 2026-09-28 (`fix/editor-lock-fork-race`), before any release
|
||||
(`FileEditor` dates from 2026-09-26). Spurious `Error::Locked` only; no
|
||||
data was affected. Nothing for users to do.
|
||||
|
||||
`FileEditor` locks its file with `flock`, which belongs to the open file
|
||||
description and lasts until every descriptor of it is closed. When another
|
||||
thread of the program forked to spawn a process (any
|
||||
`std::process::Command`), the child inherited the descriptor and kept it
|
||||
until it exec'd (close-on-exec acts only at `exec`), so an `open` of the
|
||||
same file right after the editor was dropped could be refused with
|
||||
`Error::Locked`. It showed up as a one-off failure of
|
||||
`edit_interop::editor_locks_the_file` in a full parallel `cargo test`;
|
||||
the deliberate reproducer
|
||||
(`edit_tests::drop_releases_the_lock_while_other_threads_spawn_processes`:
|
||||
four threads running `true` in a loop while the main thread opens and drops
|
||||
an editor 2000 times) had 1483 of 2000 reopens refused on tank. The drop
|
||||
now unlocks the file explicitly before closing it, which releases the lock
|
||||
for every descriptor of the description: 0 refused in 30 runs of the same
|
||||
test. The agent store's `<store>.h5.lock` (`HDF5Memory`, since v2.3.0)
|
||||
had the same pattern, hidden by its 250 ms retry on open; it unlocks on
|
||||
drop too.
|
||||
|
||||
An `fcntl` open-file-description lock (`F_OFD_SETLK`) would not have
|
||||
helped: it is inherited across `fork` the same way, and on Linux it does
|
||||
not conflict with `flock`, so libhdf5 (h5py), which locks with `flock`,
|
||||
would no longer be refused while an editor holds the file.
|
||||
|
||||
## `ObjectHeader::parse` 4% slower after range-read M2/M3
|
||||
|
||||
**Status:** fixed 2026-09-27 (`96086ad`, PR #21), before any release.
|
||||
|
||||
Reference in New Issue
Block a user