Terminate-then-kill a spawned child without touching its pipes. The drain threads own the pipes — never communicate() here (that would race a second reader against them on the same fd).
(process: subprocess.Popen)
| 293 | |
| 294 | |
| 295 | def _terminate_process(process: subprocess.Popen) -> None: |
| 296 | """Terminate-then-kill a spawned child without touching its pipes. |
| 297 | |
| 298 | The drain threads own the pipes — never communicate() here (that would |
| 299 | race a second reader against them on the same fd). |
| 300 | """ |
| 301 | try: |
| 302 | process.terminate() |
| 303 | process.wait(timeout=5) |
| 304 | except Exception: |
| 305 | process.kill() |
| 306 | try: |
| 307 | process.wait(timeout=5) # reap; a kill without wait leaves a zombie |
| 308 | except Exception: # pragma: no cover - unkillable child |
| 309 | pass |
| 310 | |
| 311 | |
| 312 | def _wait_until_ready( |
no outgoing calls
no test coverage detected