Skip to main content

Module lock

Module lock 

Source
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:

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§

ReaderLock
RAII guard for a held reader-lock byte. Dropping the guard releases the OS-side lock.
WriterLock
RAII guard for a held WRITER_LOCK byte. Dropping the guard releases the OS-side lock. The guard is !Send only 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-lock sidecar. See WRITER_LOCK_OFFSET for the sidecar rationale.
WRITER_LOCK_OFFSET
Byte offset of the WRITER_LOCK (1 byte, exclusive) inside the <db>.obj-lock sidecar file.