https://gitlab.synchro.net/main/sbbs/-/commit/13d94e64515bba9c62164314
Added Files:
exec/tests/socket/listening-close.js
Modified Files:
src/sbbs3/js_socket.cpp js_socket.h
Log Message:
js: close a ListeningSocket's listeners on close() and finalize (#1296)
A ListeningSocket keeps its listeners in a socket set and has no
sock, so do_js_close() returned at its INVALID_SOCKET check before
closing anything, and js_finalize_socket() skipped the set because the
object is marked external. Neither close() nor garbage collection
released the port: a script re-run in the same process (jsexec -l, a
looping static service, the IRCd's /RESTART) either failed to bind
(Unix) or bound a second listener beside the orphaned one (Windows with SO_REUSEADDR).
do_js_close() now destroys the set, after removing its event handlers.
A new set_owned flag, set only by the ListeningSocket constructor,
limits that to sets the script created: a static service's
server.socket wraps the set that Services owns and destroys itself, and
is marked external too, so destroying every set here would have freed
that one twice. A closed ListeningSocket then behaves like a closed
Socket.
The free(p->set) in js_finalize_socket() is removed: no non-external
socket has a set, so it never ran.
Add exec/tests/socket/listening-close.js: the port can be bound again
after close(), after a second close(), after garbage collection, and
after close() with a read handler installed.
Co-Authored-By: Claude Fable 5.1 <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net