Expand description
Cross-process byte-range file locking.
M6 issue #44. POSIX uses OFD fcntl locks (F_OFD_SETLK /
F_OFD_SETLKW) — kernel-tracked per-fd, fork-safe, automatically
released on process exit. Windows uses LockFileEx /
UnlockFileEx.
Locks anchor against a dedicated <db>.obj-lock sidecar file
created by Db::open next to the main database (mirroring the
existing <db>.obj-wal sidecar convention). Using a sidecar
decouples the lock-byte range from any region the pager may
read or write, so the lock byte offsets can be the same on
every platform and need not be placed past EOF:
WRITER_LOCK_OFFSET= 96 (exclusive, 1 byte).READER_LOCK_RANGE_OFFSET= 97..128 (shared, 31 slots).
On Windows LockFileEx produces mandatory byte-range locks.
Issue #1: prior versions placed the Windows lock anchor at
0x4000_0000 (past EOF of an empty file) so that pager I/O
could not overlap the locked range. That assumption broke when
the main DB file grew past 1 GiB — any page write whose offset
crossed 0x4000_0000 failed with ERROR_LOCK_VIOLATION. The
sidecar fixes the hazard structurally: the lock handle and the
pager handle target different files, so no pager I/O can
ever overlap a lock byte regardless of how large the DB grows.
See docs/format.md § File locking.
The lock state lives in the OS kernel’s per-fd lock table — the
bytes on disk are never read or written by obj. See
docs/format.md § File locking and § Reader snapshots (MVCC)
for the user-visible protocol.
§unsafe policy
rustix::fs::fcntl_lock does whole-file locking with F_SETLK*,
not OFD locks. We therefore call libc::fcntl directly with the
OFD command IDs. On Windows we call LockFileEx /
UnlockFileEx via windows-sys. Every unsafe block carries a
// SAFETY: comment per power-of-ten Rule 8.
Structs§
- Reader
Lock - RAII guard for a held reader-lock byte. Dropping the guard releases the OS-side lock.
- Writer
Lock - RAII guard for a held
WRITER_LOCKbyte. Dropping the guard releases the OS-side lock. The guard is!Sendonly by virtue of the file handle it does NOT own — the underlying lock is per-fd, so as long as the fd survives, releasing from any thread is sound.
Constants§
- READER_
LOCK_ RANGE_ LEN - Length of the reader-lock byte range. 31 slots.
- READER_
LOCK_ RANGE_ OFFSET - Byte offset of the first reader-lock slot inside the
<db>.obj-locksidecar. SeeWRITER_LOCK_OFFSETfor the sidecar rationale. - WRITER_
LOCK_ OFFSET - Byte offset of the
WRITER_LOCK(1 byte, exclusive) inside the<db>.obj-locksidecar file.