https://gitlab.synchro.net/main/sbbs/-/commit/aa673afdf1543e90e582478b
Modified Files:
src/sbbs3/userdat.c userdat.h src/xpdev/filewrap.c filewrap.h
Log Message:
xpdev/filewrap: shared read locks (rdlock) so user.tab reads don't serialize on Windows/SMB
xp_lockfile() on Windows used _locking(), which offers exclusive locks
only, so every byte-range lock - even a read-only record read - was
exclusive. The POSIX implementation already takes a *shared* lock
(F_RDLCK) for descriptors opened O_RDONLY, so this was a silent
cross-platform divergence dating to the original xpdev (f3f66b77d, lake-3-indigenous).
readuserdat() locks every user.tab record it reads (for consistency
against concurrent writers). On Windows that lock was exclusive, so two read-only getuserdat() calls on the same record serialized - and with
the data directory on an SMB share, each lock/unlock is a network
round-trip and the 200-attempt retry loop becomes a lock convoy. Under a web-scrape / login-probe flood, read-only lookups of hot records (e.g.
user #1) serialize across every server sharing the mount, starving
legitimate user.tab access. (GitLab #1153.)
Add a shared-lock primitive:
- xpdev: rdlock() - POSIX F_RDLCK; Windows LockFileEx without
LOCKFILE_EXCLUSIVE_LOCK (the only Windows API offering shared
byte-range locks). On Windows, lock()/xp_lockfile() and unlock() move
to the LockFileEx/UnlockFileEx family so exclusive and shared locks
pair with a single UnlockFileEx (a LockFileEx lock can't be released
with _locking(LK_UNLCK)). Borland keeps the legacy _locking path.
- sbbs3: rdlockuserdat(); readuserdat() takes a shared lock for
read-only access (leave_locked == false) and an exclusive lock when
the lock is held for a subsequent write.
Concurrent readers of a user record now proceed in parallel; writers and
the read-modify-write path stay exclusive. smblib, node.dab, the access
log, and the JS/Baja file.lock() API are unchanged (all correctly remain exclusive).
Build-verified under MSVC (Win32 Release: filewrap.c, userdat.c compile; sbbs.dll links). POSIX (GCC/Clang) and the Borland xpdev build not
compiled here; not yet runtime-tested against the live SMB install.
Co-Authored-By: Claude Opus 4.8 (1M context) <
[email protected]>
---
■ Synchronet ■ Vertrauen ■ Home of Synchronet ■ [vert/cvs/bbs].synchro.net