diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 33e62fe231e1877..0e452883963c171 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -524,11 +524,6 @@ def _terminate_broken(self, cause): self.call_queue._terminate_broken() - # gh-107219: Close the connection writer which can unblock - # Queue._feed() if it was stuck in send_bytes(). - if sys.platform == 'win32': - self.call_queue._writer.close() - # clean up resources self._join_executor_internals(broken=True) diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index d36de75749f4edf..852ae87b2768612 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -164,6 +164,11 @@ def _terminate_broken(self): # gh-94777: Prevent queue writing to a pipe which is no longer read. self._reader.close() + # gh-107219: Close the connection writer which can unblock + # Queue._feed() if it was stuck in send_bytes(). + if sys.platform == 'win32': + self._writer.close() + self.close() self.join_thread() diff --git a/Misc/NEWS.d/next/Library/2023-09-25-02-11-14.gh-issue-114440.b2TrqG.rst b/Misc/NEWS.d/next/Library/2023-09-25-02-11-14.gh-issue-114440.b2TrqG.rst new file mode 100644 index 000000000000000..7231a3c4ef83258 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-09-25-02-11-14.gh-issue-114440.b2TrqG.rst @@ -0,0 +1,6 @@ +On Windows, closing the connection writer when cleaning up a broken +:class:`multiprocessing.Queue` queue is now done for all queues, rather than +only in :mod:`concurrent.futures` manager thread. +This can prevent a deadlock when a ``multiprocessing`` worker process terminates +without cleaning up. +This completes the backport of patches by Victor Stinner and Serhiy Storchaka.