• docs/v322_new.md exec/tests/qwkjob/hub.js src/sbbs3/nopen.c qwk.cpp qw

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Mon Oct 26 00:09:03 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/251c99b699627b5dbad0ad3b
    Modified Files:
    docs/v322_new.md exec/tests/qwkjob/hub.js src/sbbs3/nopen.c qwk.cpp qwkjob.cpp qwkjob.h
    Log Message:
    fmutex_close(): remove only our own lock file; hub lock ages out at 12 h

    fmutex_open() takes over a lock file older than its max_age, and nothing refreshes a lock's time stamp while it is held. fmutex_close() then
    unlinked by name, so a holder that outlived max_age removed the lock of
    the process that took it over, leaving the next job free to run beside
    it. On POSIX, fmutex_close() now unlinks only when the open descriptor and
    the named file have the same device and inode; a missing or different file
    is no longer ours and is left alone. The descriptor is now always closed:
    a failed unlink used to return early and leak it. (Windows deletes on
    close and is unchanged.)

    The QWKnet hub lock is held across the event thread's call-out, which can
    run longer than the hour that QWK job locks were given for a crashed
    holder. The hub lock goes back to 12 hours (QWKJOB_HUB_LOCK_MAX_AGE, as
    before the QWK job locks); the per-user and REP locks, held only for one
    pack or import, keep 1 hour (QWKJOB_USER_LOCK_MAX_AGE).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net