Bug report
Bug description:
On the proactor event loop (the default on Windows), BaseProactorEventLoop._start_serving()'s loop() callback runs protocol_factory() and transport creation in the same callback that re-arms accept(), guarded only by except OSError / except CancelledError. When protocol_factory() or _make_ssl_transport() / _make_socket_transport() raises for an accepted connection:
- a non-
OSError (e.g. a failing protocol_factory) propagates out of loop(): the accepted socket is never closed (it leaks until garbage collection) and accept is not re-armed, so the server stops accepting new connections;
- an
OSError is caught as 'Accept failed on a socket', which closes the listening socket, and still leaks the accepted socket.
This is the proactor counterpart of gh-155934 (selector accept) and gh-153133 (create_connection): an accepted socket must be closed when the transport is never created, and a per-connection failure must not tear down the listening socket or the accept loop.
Verified with mock-based tests in test_proactor_events (the same approach used for the selector fix in gh-155934), which run on all platforms.
CPython versions tested on:
CPython main
Operating systems tested on:
Windows (ProactorEventLoop)
Linked PRs
Bug report
Bug description:
On the proactor event loop (the default on Windows),
BaseProactorEventLoop._start_serving()'sloop()callback runsprotocol_factory()and transport creation in the same callback that re-armsaccept(), guarded only byexcept OSError/except CancelledError. Whenprotocol_factory()or_make_ssl_transport()/_make_socket_transport()raises for an accepted connection:OSError(e.g. a failingprotocol_factory) propagates out ofloop(): the accepted socket is never closed (it leaks until garbage collection) and accept is not re-armed, so the server stops accepting new connections;OSErroris caught as'Accept failed on a socket', which closes the listening socket, and still leaks the accepted socket.This is the proactor counterpart of gh-155934 (selector accept) and gh-153133 (
create_connection): an accepted socket must be closed when the transport is never created, and a per-connection failure must not tear down the listening socket or the accept loop.Verified with mock-based tests in
test_proactor_events(the same approach used for the selector fix in gh-155934), which run on all platforms.CPython versions tested on:
CPython main
Operating systems tested on:
Windows (ProactorEventLoop)
Linked PRs