fix(sqlite): initialise an empty --lock-file before the Windows byte lock
On the msvcrt branch of scripts/ensure_state_db_read_indexes.py the tool locked byte 0 of --lock-file right after open(..., "a+"). When that open had just created the file (or the file was empty) the lock range lay beyond EOF, which Windows refuses, so the documented locked-maintenance workflow raised instead of acquiring the lock (greptile P1). Write one byte when the lock file is empty, then seek(0) and lock as before. Only the Windows branch changes; POSIX flock is untouched and an existing (deployment-owned) lock file is never rewritten. Tests (tests/test_pr7445_readonly_review_followups.py): a strict msvcrt stand-in that refuses to lock past EOF proves the lock is taken on byte 0 of a fresh empty file, that an existing lock file keeps its content, and that a held lock still propagates before the database is touched.
This commit is contained in:
1 parent
f5a7ef2049
commit
70146b74d9
3 files changed
+98
-2
No files matched your search
@@ -26,6 +26,7 @@ silently replaced.
|
||||
import argparse
|
||||
from contextlib import closing, nullcontext
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sqlite3
|
||||
import sys
|
||||
@@ -64,6 +65,12 @@ def _exclusive_lock(lock_file):
|
||||
fcntl.flock(handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
else:
|
||||
# Lock one byte at offset 0 without blocking; raises OSError when held.
|
||||
# ``a+`` may have just created an empty file, and Windows cannot lock
|
||||
# a range beyond EOF, so make sure byte 0 exists first. An existing
|
||||
# (deployment-owned) lock file is left untouched.
|
||||
if os.fstat(handle.fileno()).st_size == 0:
|
||||
handle.write("\n")
|
||||
handle.flush()
|
||||
handle.seek(0)
|
||||
msvcrt.locking(handle.fileno(), msvcrt.LK_NBLCK, 1)
|
||||
except BaseException:
|
||||
|
||||
Reference in new issue
Block a user