https://gitlab.synchro.net/main/sbbs/-/commit/247ed952d22d98605c63cd51
Modified Files:
src/sbbs3/userdat.c
Log Message:
Don't lock every user record just to count the users
readuserdat() is built for reading a single record safely: per call it
does a filelength(), a seek, a shared byte-range lock, the read, and an
unlock. total_users() called it once per user slot, so counting the
users cost five file operations and two byte-range locks per slot.
Byte-range locks are the worst possible unit of work when the data
directory is network-mounted. They are synchronous round-trips to the
lock manager and, unlike reads, can be neither cached nor batched by the
client whatever its caching settings. Locking never made the total
atomic either - only each record read within it - so the count was
already assembled from records read at different moments.
Read the user file sequentially in bulk and split the records in memory instead. The result is unchanged: records flagged DELETED or INACTIVE
are still excluded. A record rewritten mid-scan can now be misparsed and
shift the total by one, where before it would merely have been counted
as of a slightly different moment; for a displayed total, neither is
more meaningful than the other.
For 1,457 user slots this replaces 7,286 file operations - 2,914 of them
locks - with about 25 reads and no locks, taking the scan from 85ms to
5ms with the data directory on a loopback SMB mount.
This is the same fix as 8561162afd (fighter-20-fears, 2026-07-29),
applied to the user census rather than the node list.
Co-Authored-By: Claude Opus 5 (1M context) <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net