diff options
-rw-r--r-- | docs/markdown/snippets/termination_signal_for_tests.md | 6 | ||||
-rw-r--r-- | mesonbuild/mtest.py | 27 |
2 files changed, 26 insertions, 7 deletions
diff --git a/docs/markdown/snippets/termination_signal_for_tests.md b/docs/markdown/snippets/termination_signal_for_tests.md new file mode 100644 index 0000000..e99ea16 --- /dev/null +++ b/docs/markdown/snippets/termination_signal_for_tests.md @@ -0,0 +1,6 @@ +## Changed the signal used to terminate a test process (group) + +A test process (group) is now terminated via SIGTERM instead of SIGKILL +allowing the signal to be handled. However, it is now the responsibility of +the custom signal handler (if any) to ensure that any process spawned by the +top-level test processes is correctly killed. diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 32b87c6..c35ab5a 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -578,14 +578,27 @@ class SingleTestRunner: if is_windows(): subprocess.run(['taskkill', '/F', '/T', '/PID', str(p.pid)]) else: + + def _send_signal_to_process_group(pgid : int, signum : int): + """ sends a signal to a process group """ + try: + os.killpg(pgid, signum) # type: ignore + except ProcessLookupError: + # Sometimes (e.g. with Wine) this happens. + # There's nothing we can do (maybe the process + # already died) so carry on. + pass + + # Send a termination signal to the process group that setsid() + # created - giving it a chance to perform any cleanup. + _send_signal_to_process_group(p.pid, signal.SIGTERM) + + # Make sure the termination signal actually kills the process + # group, otherwise retry with a SIGKILL. try: - # Kill the process group that setsid() created. - os.killpg(p.pid, signal.SIGKILL) # type: ignore - except ProcessLookupError: - # Sometimes (e.g. with Wine) this happens. - # There's nothing we can do (maybe the process - # already died) so carry on. - pass + p.communicate(timeout=0.5) + except subprocess.TimeoutExpired: + _send_signal_to_process_group(p.pid, signal.SIGKILL) try: p.communicate(timeout=1) except subprocess.TimeoutExpired: |