Skip to content

Commit b5f4ce6

Browse files
committed
gh-130141: clean up asyncio._SelectorTransport during __del__
aligns the SelectorTransport __del__ implementation with force_close also sets sock_fd to -1 when closing the socket so stale fds can't be reused
1 parent 39cd972 commit b5f4ce6

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

Lib/asyncio/selector_events.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -864,16 +864,37 @@ def close(self):
864864
self._closing = True
865865
self._loop._remove_reader(self._sock_fd)
866866
if not self._buffer:
867-
self._conn_lost += 1
868867
self._loop._remove_writer(self._sock_fd)
868+
self._conn_lost += 1
869869
self._loop.call_soon(self._call_connection_lost, None)
870870

871871
def __del__(self, _warn=warnings.warn):
872872
if self._sock is not None:
873-
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
873+
if self._protocol_connected:
874+
self._protocol_connected = False
875+
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
876+
877+
if self._buffer:
878+
self._buffer.clear()
879+
self._loop._remove_writer(self._sock_fd)
880+
881+
if not self._closing:
882+
self._closing = True
883+
self._loop._remove_reader(self._sock_fd)
884+
885+
self._conn_lost += 1
886+
887+
self._sock_fd = -1
874888
self._sock.close()
875-
if self._server is not None:
876-
self._server._detach(self)
889+
self._sock = None
890+
891+
self._protocol = None
892+
self._loop = None
893+
894+
server = self._server
895+
if server is not None:
896+
self._server = None
897+
server._detach(self)
877898

878899
def _fatal_error(self, exc, message='Fatal error on transport'):
879900
# Should be called from exception handler only.
@@ -904,8 +925,10 @@ def _force_close(self, exc):
904925
def _call_connection_lost(self, exc):
905926
try:
906927
if self._protocol_connected:
928+
self._protocol_connected = False
907929
self._protocol.connection_lost(exc)
908930
finally:
931+
self._sock_fd = -1
909932
self._sock.close()
910933
self._sock = None
911934
self._protocol = None
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix asyncio selector stall if :class:`!asyncio._SelectorTransport` is
2+
resurrected from GC for .close() after the fd has been reused.

0 commit comments

Comments
 (0)