Subj : docs/v322_new.md src/sbbs3/js_socket.cpp services.cpp To : Git commit to main/sbbs/master From : Rob Swindell (on Debian Linux) Date : Wed Sep 30 2026 19:08:47 https://gitlab.synchro.net/main/sbbs/-/commit/85e04a4262d8b4afb0ef5bf2 Modified Files: docs/v322_new.md src/sbbs3/js_socket.cpp services.cpp Log Message: Services: end a script's blocking socket read when it is terminated Fixes #1255 On shutdown the services thread closes the listening sockets and then waits, with no limit, for every dynamic service client to disconnect. A client blocked in Socket.recvline() only noticed the shutdown when the read's own timeout expired, since the read loop never looked at the termination flag. nntpservice.js reads with a 300-second timeout once its message base has closed, so one idle NNTP session held shutdown for up to five minutes, well past systemd's 90-second stop timeout, and the process was SIGKILLed. Backtraces from a stuck instance show exactly that: the client thread in js_recvline() with timeout=300, the services thread in its wait loop. The socket object's private data has a pointer to the script's callback struct, but it was only filled in when a script installed a socket event. Set it when every socket object is created (through a quiet lookup that returns NULL for a context without a "js" object), check it in the recvline read-check loop, and replace the single blocking wait inside js_socket_recv() with one-second steps that stop when the script is terminated, so recv() with a long timeout ends early too. Meanwhile the services thread logs, every ten seconds, which services still have clients connected and how many. Verified on a scratch services server with one idle NNTP client past its message-base close: SIGTERM to exit took more than 60 seconds before (the test gave up) and 2 seconds after. Co-Authored-By: Claude Fable 5.1 --- SBBSecho 3.38-Linux * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705) .