[PATCH v2 1/4] loose: use finite timeout when locking "loose-object-idx" file
- From
Justin Tobler <jltobler@gmail.com>
- Date
- Oct 29, 2026, 00:24 UTC
- Message-ID
- <20261029002413.3291184-2-jltobler@gmail.com>
- In-Reply-To
- <20261029002413.3291184-1-jltobler@gmail.com>
Loose object index file writers first attempt to acquire a lock via `repo_hold_lock_file_for_update_timeout()` and specify a timeout value of -1. With a negative timeout value, the lock acquisition retries indefinitely while the lockfile still exists. If a process dies while holding the lock and leaves a stale lockfile behind, every subsequent writer of the mapping file hangs forever instead of reporting an error.
Introduce LOOSE_OBJECT_IDX_LOCK_TIMEOUT_MS to set the timeout to 1000ms and use it for all callers that lock a "loose-object-idx" file. A value of 1000ms matches the default timeout used for "core.packedRefsTimeout" and should provide concurrent writers sufficient time to acquire the lock.
Signed-off-by: Justin Tobler <jltobler@gmail.com> --- loose.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/loose.c b/loose.c index d6a2bb5ba3..c6f4ee0ec6 100644 --- a/loose.c +++ b/loose.c @@ -14,6 +14,8 @@ static const char *loose_object_header = "# loose-object-idx\n"; +#define LOOSE_OBJECT_IDX_LOCK_TIMEOUT_MS 1000 + static inline int should_use_loose_object_map(struct repository *repo) { return repo->compat_hash_algo && repo->gitdir; @@ -137,7 +139,8 @@ int repo_write_loose_object_map(struct repository *repo) repo_common_path_replace(repo, &path, "objects/loose-object-idx"); fd = repo_hold_lock_file_for_update_timeout(repo, &lock, path.buf, - LOCK_DIE_ON_ERROR, -1); + LOCK_DIE_ON_ERROR, + LOOSE_OBJECT_IDX_LOCK_TIMEOUT_MS); iter = kh_begin(map); if (write_in_full(fd, loose_object_header, strlen(loose_object_header)) < 0) goto errout; @@ -180,7 +183,8 @@ static int write_one_object(struct odb_source_loose *loose, strbuf_addf(&path, "%s/loose-object-idx", loose->base.path); repo_hold_lock_file_for_update_timeout(loose->base.odb->repo, &lock, - path.buf, LOCK_DIE_ON_ERROR, -1); + path.buf, LOCK_DIE_ON_ERROR, + LOOSE_OBJECT_IDX_LOCK_TIMEOUT_MS); fd = open(path.buf, O_WRONLY | O_CREAT | O_APPEND, 0666); if (fd < 0)
-- 2.56.0.173.gf57c9a7388