Subj : src/sbbs3/ftpsrvr.c mailsrvr.cpp main.cpp services.cpp websrvr.cpp To : Git commit to main/sbbs/master From : Rob Swindell (on Windows 11) Date : Mon Feb 02 2026 08:14 pm https://gitlab.synchro.net/main/sbbs/-/commit/884fe045cf80fd67ecd6e533 Modified Files: src/sbbs3/ftpsrvr.c mailsrvr.cpp main.cpp services.cpp websrvr.cpp Log Message: Fix the race between recycle/reload and terminate/shutdown When a server (any of the 5) saw that it had been requested to recycle, it would: 1. Set the server state to RELOADING 2. Do some shutdown stuff (close sockets, wait for child threads to terminate) 3. Call cleanup(0) 3a. which would (now) *not* set the server state to STOPPED (recent change) 3b. call the startup->terminated() callback (eh?) 4. Delay 2 seconds (with no explanation why) 5. Call the startup->recycle() callback (which usually reloads the sbbs.ini) 6. And then if the ''terminate_server'' flag had been set at any time after step 1 (which is a long time now), it would just terminate the server thread, leaving the state as RELOADING. So, - I removed the inexplicable 2 second delay (added in commit c1143ea077aca8f "Recycles server on accept error") - I moved the call to cleanup() to *after* the call to the startup->recycle callback (which could take some time) - I moved the calls to the startup->terminated() callback (which appears to only be used by sbbsNTsvcs) to the if (terminate_server || code) conditional block in cleanup() The possibilty of a check of ''terminate_server'' racing with a request to recycle likely still exists somewhere, but I wasn't able to make it happen whereas it was easy to trigger the issue previous to this change. The race was previously masked because we were always setting the server to STOPPED state while recycling (a different issue, previously fixed, which unmasked this issue). A better fix would be to wrap each various server thread function in a resource management function (or heck, a class constructor/destructor in the C++ servers) and not rely on the magic of the cleanup() functions being called at the right times in the right order with global state variables galore. But that's for another day. .