for p in self.processes.values():
p.terminate()
+ # Prevent queue writing to a pipe which is no longer read.
+ # https://github.com/python/cpython/issues/94777
+ self.call_queue._reader.close()
+
# clean up resources
self.join_executor_internals()
faulthandler._sigsegv()
+def _crash_with_data(data):
+ """Induces a segfault with dummy data in input."""
+ _crash()
+
+
def _exit():
"""Induces a sys exit with exitcode 1."""
sys.exit(1)
# dangling threads
executor_manager.join()
+ def test_crash_big_data(self):
+ # Test that there is a clean exception instad of a deadlock when a
+ # child process crashes while some data is being written into the
+ # queue.
+ # https://github.com/python/cpython/issues/94777
+ self.executor.shutdown(wait=True)
+ data = "a" * support.PIPE_MAX_SIZE
+ with self.executor_type(max_workers=2,
+ mp_context=self.get_context()) as executor:
+ self.executor = executor # Allow clean up in fail_on_deadlock
+ with self.assertRaises(BrokenProcessPool):
+ list(executor.map(_crash_with_data, [data] * 10))
+
create_executor_tests(ExecutorDeadlockTest,
executor_mixins=(ProcessPoolForkMixin,