• src/sbbs3/main.cpp sbbs.h str.cpp

    From Rob Swindell (on Windows 11)@1:103/705 to Git commit to main/sbbs/master on Tue Apr 9 18:03:01 2024
    https://gitlab.synchro.net/main/sbbs/-/commit/424dfe1073b2f29f039431d8
    Modified Files:
    src/sbbs3/main.cpp sbbs.h str.cpp
    Log Message:
    Create/use sbbs_t::flush_output(timeout)

    If client socket is connected, wait up to the specified timeout period (in ms) for the output buffer to be emptied.

    This is much preferred over blindly calling mswait() after sending some data (e.g. a file) and possibly waiting much longer than necessary.
    --- SBBSecho 3.20-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell (on Windows 11)@1:103/705 to Git commit to main/sbbs/master on Tue Feb 10 03:04:28 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/e4cab7de5d2dabb47b8a8ee8
    Modified Files:
    src/sbbs3/main.cpp sbbs.h str.cpp
    Log Message:
    Enable cached filter file (ip.can, host.can) support in the terminal server
    --- SBBSecho 3.36-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell (on Windows 11)@1:103/705 to Git commit to main/sbbs/master on Sat Jun 6 02:23:46 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/9cf170c0246a40f6d502d8b1
    Modified Files:
    src/sbbs3/main.cpp sbbs.h str.cpp
    Log Message:
    Terminal server: fully transmit pre-disconnect message before close (#1157)

    Messages shown to a client immediately before disconnecting (nonodes.txt
    when all nodes are full or node init fails, and badip.msg/badhost.msg for blocked clients) were intermittently not seen by the caller.

    Root cause: these paths printed the file then called flush_output(), which waits on outbuf.empty_event. That event fires when output_thread moves the ring-buffer contents into its *linear* buffer (RingBufRead), not when those bytes are actually sent over the socket. flush_output() therefore returned
    in the gap between ring->linear hand-off and the sendsocket(), the caller closed the socket, and output_thread's send then failed on the closed FD ("!ERROR ... sending on socket"). The result was a thread-scheduling race, matching the reporter's intermittent, protocol-independent symptom.

    Add sbbs_t::WaitForOutbufDrained(timeout): wait for the ring buffer to
    empty AND for output_thread's linear buffer to be transmitted, tracked via
    a new output_thread_busy atomic (set before the ring->linear read so the empty_event hand-off can't be mistaken for "everything sent", cleared once
    the linear buffer is fully sent). Use it in place of flush_output() at the
    two nonodes.txt disconnect sites (main.cpp) and in trashcan_msg() (str.cpp).

    flush_output() is retained for outcom()'s transmit-backpressure retry loop, where "wait for ring-buffer space" (with its online short-circuit) is the correct semantics.

    The nonodes drop-before-close pattern is from ff1aae498 (same-3-jazz); trashcan_msg()'s flush_output(500) is from 424dfe107 (cold-36-task); the underlying empty_event-means-ring-drained-not-sent gap is inherent to the two-stage output_thread design.

    Reported by xbit with detailed cross-client testing.

    Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)