You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(local_store): DocStore.lock() no-op on Windows causes race condition and duplicate document names #561
[Bug] Windows concurrency defect in DocStore.lock() causes duplicate document names during concurrent submissions
Description
In pageindex/local_store.py, DocStore.lock() uses fcntl.flock() for file locking:
try:
importfcntlexceptImportError:
yieldreturn
On Windows, fcntl is unavailable in the Python standard library. When importing it raises ImportError, the context manager silently yields without acquiring a lock. The current implementation also does not provide an in-process thread lock as a fallback.
As a result, concurrent calls to LocalAPI.submit_document() on Windows can execute the document-name check-and-save sequence (_unique_doc_name() followed by _store.save_document()) without mutual exclusion.
Two callers may both observe that the same filename is available (for example, sample.pdf) and save documents under that name, violating the intended unique-name invariant.
The test expects concurrent submissions of the same file to receive distinct stored names.
CI Consideration
The current .github/workflows/tests.yml workflow uses ubuntu-latest. Since the locking implementation takes a different path on Windows, adding Windows CI coverage would help detect platform-specific concurrency regressions.
Requested behavior and acceptance criteria
Concurrent submissions of documents with the same filename must receive distinct stored names. Neither submission should silently overwrite or shadow the other because of a naming collision.
The filename uniqueness check and document save operation must execute within the same protected critical section, preventing concurrent callers from selecting the same available name.
Thread safety must be guaranteed when multiple threads submit documents through the same DocStore.
Separate DocStore instances targeting the same storage directory must coordinate correctly, rather than relying only on instance-local synchronization.
Cross-process locking must continue to work on POSIX systems using fcntl.flock().
Windows must provide equivalent cross-process locking guarantees through an appropriate platform-specific mechanism, such as msvcrt.locking(), rather than silently proceeding without a lock.
Nested lock acquisition and release must behave safely, without deadlocks, premature lock release, or platform-specific locking errors.
Deterministic tests must cover concurrent same-name submissions and relevant thread-level and cross-process locking behavior, including Windows-specific behavior where applicable.
Existing storage semantics, document identifiers, and document submission behavior must remain backward compatible.
Proposed direction
Implement cross-platform synchronization that combines in-process thread safety with operating-system-level file locking. Ensure that lock-file creation, acquisition, release, and reentrancy are handled correctly.
The implementation should preserve existing POSIX behavior while providing equivalent concurrency guarantees on Windows. The exact internal design can be determined during implementation and review.
The bug is real: on Windows import fcntl raises ImportError and DocStore.lock() silently yields with no lock, so concurrent submit_document calls can race the check-and-save in _unique_doc_name + _store.save_document and produce duplicate names.
My plan:
Add a cross-platform exclusive lock: fcntl.flock on POSIX (unchanged), msvcrt.locking on Windows for the cross-process case, plus an in-process threading.Lock so threads within one process also serialize.
Keep the unique-name check and the document save inside the same critical section so the invariant holds under concurrency.
Add a regression test simulating the Windows path (no fcntl) with concurrent same-name submissions asserting distinct stored names.
Look into adding a Windows runner to the tests workflow as follow-up.
Activity
Varshith-Kali commentedon Oct 17, 2026
I'd like to take this one.
The bug is real: on Windows
import fcntlraisesImportErrorandDocStore.lock()silently yields with no lock, so concurrentsubmit_documentcalls can race the check-and-save in_unique_doc_name+_store.save_documentand produce duplicate names.My plan:
fcntl.flockon POSIX (unchanged),msvcrt.lockingon Windows for the cross-process case, plus an in-processthreading.Lockso threads within one process also serialize.fcntl) with concurrent same-name submissions asserting distinct stored names.I'll open a PR with the fix and tests.