diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2011-04-08 10:57:06 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2011-04-08 10:57:06 (GMT) |
commit | de10f4054b6bd6dd286559d7bbaaff7364282fc7 (patch) | |
tree | 9540bf576e1ce6f8be8e400c9c5e6f108f494544 /Lib/test/test_faulthandler.py | |
parent | cfa7123ef108452dd402e3cdcec772be28872e2f (diff) | |
download | cpython-de10f4054b6bd6dd286559d7bbaaff7364282fc7.zip cpython-de10f4054b6bd6dd286559d7bbaaff7364282fc7.tar.gz cpython-de10f4054b6bd6dd286559d7bbaaff7364282fc7.tar.bz2 |
faulthandler: one more time, fix usage of locks in the watchdog thread
* Write a new test to ensure that dump_tracebacks_later() still works if
it was already called and then cancelled before
* Don't use a variable to check the status of the thread, only rely on locks
* The thread only releases cancel_event if it was able to acquire it (if
the timer was interrupted)
* The main thread always hold this lock. It is only released when
faulthandler_thread() is interrupted until this thread exits, or at Python
exit.
Diffstat (limited to 'Lib/test/test_faulthandler.py')
-rw-r--r-- | Lib/test/test_faulthandler.py | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index bfe662e..483c7f1 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -352,7 +352,7 @@ Current thread XXX: with temporary_filename() as filename: self.check_dump_traceback_threads(filename) - def _check_dump_tracebacks_later(self, repeat, cancel, filename): + def _check_dump_tracebacks_later(self, repeat, cancel, filename, loops): """ Check how many times the traceback is written in timeout x 2.5 seconds, or timeout x 3.5 seconds if cancel is True: 1, 2 or 3 times depending @@ -364,42 +364,43 @@ Current thread XXX: import faulthandler import time -def func(repeat, cancel, timeout): - if cancel: +def func(timeout, repeat, cancel, file, loops): + for loop in range(loops): + faulthandler.dump_tracebacks_later(timeout, repeat=repeat, file=file) + if cancel: + faulthandler.cancel_dump_tracebacks_later() + time.sleep(timeout * 2.5) faulthandler.cancel_dump_tracebacks_later() - time.sleep(timeout * 2.5) - faulthandler.cancel_dump_tracebacks_later() timeout = {timeout} repeat = {repeat} cancel = {cancel} +loops = {loops} if {has_filename}: file = open({filename}, "wb") else: file = None -faulthandler.dump_tracebacks_later(timeout, - repeat=repeat, file=file) -func(repeat, cancel, timeout) +func(timeout, repeat, cancel, file, loops) if file is not None: file.close() """.strip() code = code.format( - filename=repr(filename), - has_filename=bool(filename), + timeout=TIMEOUT, repeat=repeat, cancel=cancel, - timeout=TIMEOUT, + loops=loops, + has_filename=bool(filename), + filename=repr(filename), ) trace, exitcode = self.get_output(code, filename) trace = '\n'.join(trace) if not cancel: + count = loops if repeat: - count = 2 - else: - count = 1 + count *= 2 header = 'Thread 0x[0-9a-f]+:\n' - regex = expected_traceback(7, 19, header, count=count) + regex = expected_traceback(9, 20, header, count=count) self.assertRegex(trace, regex) else: self.assertEqual(trace, '') @@ -408,12 +409,17 @@ if file is not None: @unittest.skipIf(not hasattr(faulthandler, 'dump_tracebacks_later'), 'need faulthandler.dump_tracebacks_later()') def check_dump_tracebacks_later(self, repeat=False, cancel=False, - file=False): + file=False, twice=False): + if twice: + loops = 2 + else: + loops = 1 if file: with temporary_filename() as filename: - self._check_dump_tracebacks_later(repeat, cancel, filename) + self._check_dump_tracebacks_later(repeat, cancel, + filename, loops) else: - self._check_dump_tracebacks_later(repeat, cancel, None) + self._check_dump_tracebacks_later(repeat, cancel, None, loops) def test_dump_tracebacks_later(self): self.check_dump_tracebacks_later() @@ -427,6 +433,9 @@ if file is not None: def test_dump_tracebacks_later_file(self): self.check_dump_tracebacks_later(file=True) + def test_dump_tracebacks_later_twice(self): + self.check_dump_tracebacks_later(twice=True) + @unittest.skipIf(not hasattr(faulthandler, "register"), "need faulthandler.register") def check_register(self, filename=False, all_threads=False, |