• docs/v322_new.md src/sbbs3/js_internal.cpp js_socket.cpp js_socket.h

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Wed Nov 11 13:56:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/38c93be5ba8d0cd42049e8d6
    Modified Files:
    docs/v322_new.md src/sbbs3/js_internal.cpp js_socket.cpp js_socket.h Log Message:
    js: don't block a non-blocking TLS socket's send on an idle peer

    cryptlib's write timeout defaults to 5 seconds and Socket never changed
    it, so send() on a TLS socket whose peer had stopped reading held the
    script for 5 seconds in the push and again in the flush, even with
    nonblocking set. In an event-driven script (the IRC daemon) that froze
    every other connection and timer for as long as one peer was slow.

    A non-blocking TLS socket now gets a zero write timeout, and the
    session's own timeout back if the script makes it blocking again. A
    flush that cannot finish is no longer an error: js_handle_events()
    retries it, for sockets with a read event, and wakes every 20 ms while
    any output is waiting. cryptlib waits 5 ms or more on the descriptor
    even with a zero timeout, so send() and the retry first check that the
    socket is writable.

    Socket.sendfile() on a non-blocking TLS socket would now give up as
    soon as the peer's window filled, so it waits for room and retries, as
    it does for a plain socket.

    Not changed: a script that sends on a non-blocking TLS socket without
    a read event keeps unsent output until its next send, and close()
    discards what the peer has not taken rather than waiting for it.

    Built with MSVC and GCC. On Windows, 600 KB sent to a peer idle for
    20 seconds: longest send() 10.02 s before, 0.019 s after, with every
    byte delivered.

    Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

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