Skip to content

Commit 8950689

Browse files
[3.11] GH-89237: fix hang in proactor subprocess.wait_closed() (GH-98572) (#98620)
GH-89237: fix hang in proactor `subprocess.wait_closed()` (GH-98572) (cherry picked from commit ad1dc3e) Co-authored-by: Kumar Aditya <[email protected]>
1 parent 5fb3b61 commit 8950689

File tree

3 files changed

+10
-2
lines changed

3 files changed

+10
-2
lines changed

Lib/asyncio/proactor_events.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def __init__(self, loop, sock, protocol, waiter=None,
6060
self._pending_write = 0
6161
self._conn_lost = 0
6262
self._closing = False # Set when close() called.
63+
self._called_connection_lost = False
6364
self._eof_written = False
6465
if self._server is not None:
6566
self._server._attach()
@@ -136,7 +137,7 @@ def _force_close(self, exc):
136137
self._empty_waiter.set_result(None)
137138
else:
138139
self._empty_waiter.set_exception(exc)
139-
if self._closing:
140+
if self._closing and self._called_connection_lost:
140141
return
141142
self._closing = True
142143
self._conn_lost += 1
@@ -166,6 +167,7 @@ def _call_connection_lost(self, exc):
166167
if server is not None:
167168
server._detach()
168169
self._server = None
170+
self._called_connection_lost = True
169171

170172
def get_write_buffer_size(self):
171173
size = self._pending_write

Lib/test/test_asyncio/test_proactor_events.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,12 @@ def test_force_close_idempotent(self):
290290
tr._closing = True
291291
tr._force_close(None)
292292
test_utils.run_briefly(self.loop)
293-
self.assertFalse(self.protocol.connection_lost.called)
293+
# See https://github.com/python/cpython/issues/89237
294+
# `protocol.connection_lost` should be called even if
295+
# the transport was closed forcefully otherwise
296+
# the resources held by protocol will never be freed
297+
# and waiters will never be notified leading to hang.
298+
self.assertTrue(self.protocol.connection_lost.called)
294299

295300
def test_fatal_error_2(self):
296301
tr = self.socket_transport()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix hang on Windows in ``subprocess.wait_closed()`` in :mod:`asyncio` with :class:`~asyncio.ProactorEventLoop`. Patch by Kumar Aditya.

0 commit comments

Comments
 (0)