This was left out of the 3.12 backport for three related issues:
- gh-107219 (which adds `self.call_queue._writer.close()` to `_ExecutorManagerThread` in `concurrent.futures`)
- gh-109370 (which changes this to be only called on Windows)
- gh-109047 (which moves the call to `multiprocessing.Queue`'s `_terminate_broken`)
Without this change, ProcessPoolExecutor sometimes hangs on Windows
when a worker process is terminated.
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
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)
# 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()
--- /dev/null
+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.