diff options
Diffstat (limited to 'Lib/test/test_io.py')
| -rw-r--r-- | Lib/test/test_io.py | 45 | 
1 files changed, 44 insertions, 1 deletions
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 9fb85f21e2..2d02a3103c 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -35,7 +35,7 @@ import weakref  from collections import deque, UserList  from itertools import cycle, count  from test import support -from test.script_helper import assert_python_ok +from test.script_helper import assert_python_ok, run_python_until_end  import codecs  import io  # C implementation of io @@ -3437,6 +3437,49 @@ class CMiscIOTest(MiscIOTest):          b = bytearray(2)          self.assertRaises(ValueError, bufio.readinto, b) +    @unittest.skipUnless(threading, 'Threading required for this test.') +    def check_daemon_threads_shutdown_deadlock(self, stream_name): +        # Issue #23309: deadlocks at shutdown should be avoided when a +        # daemon thread and the main thread both write to a file. +        code = """if 1: +            import sys +            import time +            import threading + +            file = sys.{stream_name} + +            def run(): +                while True: +                    file.write('.') +                    file.flush() + +            thread = threading.Thread(target=run) +            thread.daemon = True +            thread.start() + +            time.sleep(0.5) +            file.write('!') +            file.flush() +            """.format_map(locals()) +        res, _ = run_python_until_end("-c", code) +        err = res.err.decode() +        if res.rc != 0: +            # Failure: should be a fatal error +            self.assertIn("Fatal Python error: could not acquire lock " +                          "for <_io.BufferedWriter name='<{stream_name}>'> " +                          "at interpreter shutdown, possibly due to " +                          "daemon threads".format_map(locals()), +                          err) +        else: +            self.assertFalse(err.strip('.!')) + +    def test_daemon_threads_shutdown_stdout_deadlock(self): +        self.check_daemon_threads_shutdown_deadlock('stdout') + +    def test_daemon_threads_shutdown_stderr_deadlock(self): +        self.check_daemon_threads_shutdown_deadlock('stderr') + +  class PyMiscIOTest(MiscIOTest):      io = pyio  | 
