Fix process tree cancellation for tools

This commit is contained in:
武阳
2026-05-09 11:36:59 +08:00
parent 323ee23cd6
commit eea7e2f1b3
3 changed files with 141 additions and 8 deletions
+29 -3
View File
@@ -8,9 +8,11 @@ from __future__ import annotations
import asyncio
import json
import os
import queue
import re
import shutil
import signal
import threading
import time
import venv
@@ -270,7 +272,7 @@ class RunProcessRegistry:
for process in processes:
try:
if process.poll() is None:
process.terminate()
self._signal_process_tree(process, signal.SIGTERM)
except OSError:
continue
deadline = time.monotonic() + 1.0
@@ -279,11 +281,35 @@ class RunProcessRegistry:
remaining = max(0.0, deadline - time.monotonic())
process.wait(timeout=remaining)
except Exception:
self._signal_process_tree(process, signal.SIGKILL)
try:
process.kill()
except OSError:
process.wait(timeout=1.0)
except Exception:
pass
@staticmethod
def _signal_process_tree(process: Any, sig: signal.Signals) -> None:
try:
if os.name == 'posix':
pgid = os.getpgid(process.pid)
if pgid == process.pid:
os.killpg(pgid, sig)
return
if sig == signal.SIGTERM:
process.terminate()
else:
process.kill()
except ProcessLookupError:
return
except OSError:
try:
if sig == signal.SIGTERM:
process.terminate()
else:
process.kill()
except OSError:
pass
@dataclass
class RunRecord: