diff options
author | Mark Nemec <mrknmc@me.com> | 2018-04-10 17:23:14 (GMT) |
---|---|---|
committer | Antoine Pitrou <pitrou@free.fr> | 2018-04-10 17:23:14 (GMT) |
commit | c4b695f85e141f57d22d8edf7bc2c756da136918 (patch) | |
tree | 73fee6f3f23c9d7b0496a27de71c4ca319b793f6 /Lib/test/test_concurrent_futures.py | |
parent | f178028f37c9dafb72608b719eb03e5a70af4ff5 (diff) | |
download | cpython-c4b695f85e141f57d22d8edf7bc2c756da136918.zip cpython-c4b695f85e141f57d22d8edf7bc2c756da136918.tar.gz cpython-c4b695f85e141f57d22d8edf7bc2c756da136918.tar.bz2 |
bpo-33097: Fix submit accepting callable after executor shutdown by interpreter exit (GH-6144)
Executors in concurrent.futures accepted tasks after executor was shutdown by interpreter exit. Tasks were left in PENDING state forever. This fix changes submit to instead raise a RuntimeError.
Diffstat (limited to 'Lib/test/test_concurrent_futures.py')
-rw-r--r-- | Lib/test/test_concurrent_futures.py | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 18d0265..b258a0e 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -303,6 +303,34 @@ class ExecutorShutdownTest: self.assertFalse(err) self.assertEqual(out.strip(), b"apple") + def test_submit_after_interpreter_shutdown(self): + # Test the atexit hook for shutdown of worker threads and processes + rc, out, err = assert_python_ok('-c', """if 1: + import atexit + @atexit.register + def run_last(): + try: + t.submit(id, None) + except RuntimeError: + print("runtime-error") + raise + from concurrent.futures import {executor_type} + if __name__ == "__main__": + context = '{context}' + if not context: + t = {executor_type}(5) + else: + from multiprocessing import get_context + context = get_context(context) + t = {executor_type}(5, mp_context=context) + t.submit(id, 42).result() + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, "ctx", ""))) + # Errors in atexit hooks don't change the process exit code, check + # stderr manually. + self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) + self.assertEqual(out.strip(), b"runtime-error") + def test_hang_issue12364(self): fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] self.executor.shutdown() |