LSP: forced shutdown stays within its deadline under load

Merged
AF
3d ago
+206-70

shutdown_all promises to return within 1.5 s, including force-killing language servers that ignore the stop request. On a loaded macOS runner it took 1.73 s with six such servers. Each forced kill ran one at a time on the caller's thread, and each also waited for the lock that starting a new process holds, so a slow process start delayed the remaining kills.

Now every kill goes out first and reaping runs off the caller's thread, so the call returns on time. Any server not yet reaped is reported as still running (all are gone within 2 s).

Proof: with a controlled spawn-lock delay on a loaded macOS machine, the shutdown test failed 20 of 20 runs before the fix and passed 20 of 20 after. The original CI failure never reproduced without the delay. The build server refused the pre-push run as full (runner_full), so CI is this PR's test gate.


Summary by cubic

Fixes LSP shutdown so shutdown_all returns within its 1.5s ceiling even when force-killing unresponsive servers on a loaded machine (it previously took 1.73s with six such servers). Forced kills are now dispatched to every process group before per-kill registry cleanup, and reaping continues off the caller's thread; any server not yet reaped at the deadline is reported as unreaped and finishes within 2s.

With a controlled spawn-lock delay, the regression failed 20 of 20 runs before this change and passes 20 of 20 after. The build server refused the pre-push run, so CI is this PR's gate.