Skip to content

lsp: drop the reaper-race workaround, which has nothing left to race - #217

Merged
pcarrier merged 1 commit into
mainfrom
eng/lsp-drop-reap-backstop
Aug 6, 2026
Merged

lsp: drop the reaper-race workaround, which has nothing left to race#217
pcarrier merged 1 commit into
mainfrom
eng/lsp-drop-reap-backstop

Conversation

@pcarrier

@pcarrier pcarrier commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #204/#211, found while auditing which subsystems still reap their own children.

#204 narrowed the daemon's backstop from draining waitpid(-1) to sweeping PTY-owned pids only. It no longer touches LSP children at all, and three things in this crate still describe the world before that:

  • reap_backstop_status was already an empty stub (fn reap_backstop_status(_pid: u32) {}) whose doc comment explained a pid-recycling collision it no longer prevents. It and its two call sites go, along with the pid bindings that existed only to feed it.
  • The try_wait comment still warned that "the daemon's global reaper may win the race and steal the status". It cannot. What's left is the ordinary case — an Err means the child is already gone — so the comment says that.
  • docs/design/lsp.md § Reaping described the backstop as reaping every child while parking statuses selectively. It reaps selectively now too.

No behaviour change; the stub did nothing.

On the doc

I rewrote that bullet rather than deleting it, because the consequence is worth keeping and is not obvious: now that the backstop only sweeps what it owns, a subsystem that doesn't wait its own children leaks zombies instead of being quietly mopped up. That makes the engine's every-path wait() load-bearing rather than defensive.

That's not hypothetical — it's exactly what #211 had to fix for the audio pipeline, where is_alive was the only thing collecting children and it only ran from the delivery tick. The LSP engine was already correct here; the note is so the next person adding a subprocess knows the floor moved.

nix run .#lint exit 0, cargo test -p blit-lsp 39 passing.

#204 narrowed the daemon's backstop from draining `waitpid(-1)` to
sweeping PTY-owned pids only, so it no longer touches LSP children at
all. Three things in this crate still describe the world before that.

`reap_backstop_status` was already an empty stub whose doc comment
explained a collision it no longer prevents; it and its two call sites
go, along with the `pid` bindings that existed only to feed it.

The comment on the shutdown `try_wait` still warned that "the daemon's
global reaper may win the race and steal the status". It cannot. What is
left is the ordinary case — an `Err` means the child is already gone —
so the comment says that instead.

`docs/design/lsp.md` § Reaping described the backstop as reaping every
child and parking statuses selectively. It now reaps selectively too, so
the trap it names is gone. The replacement records the consequence
rather than deleting the note, because the consequence is the part worth
keeping: a subsystem that does not wait its own children now leaks
zombies instead of being quietly mopped up, which is what made the
engine's every-path `wait()` load-bearing rather than defensive. That
same narrowing is what #211 had to fix for the audio pipeline.

No behaviour change — the stub did nothing.
@indent

indent Bot commented Aug 6, 2026

Copy link
Copy Markdown
PR Summary

Removes LSP-crate code and docs that still described the pre-#204 reaper world. #204 narrowed the daemon's backstop from an unconditional waitpid(-1) drain to sweeping PTY-owned pids only, so it no longer touches LSP children; the workaround this PR deletes was already a no-op. Verified as a pure cleanup with no behavior change: both engine teardown paths still wait()/kill() the child, and the doc's claim matches the actual reap_zombies implementation.

  • Delete reap_backstop_status (an empty {} stub) and its two call sites in Engine::shutdown and Engine::on_child_gone, plus the pid bindings that only fed it.
  • Rewrite the shutdown try_wait comment: no reaper race remains, so an Err just means the child is already gone.
  • Rewrite docs/design/lsp.md § Reaping to describe the selective backstop and record the corollary — a subsystem that doesn't wait its own children now leaks zombies, making the engine's every-path wait() load-bearing.

Issues

Review closed.

View session

@pcarrier
pcarrier merged commit 53f8a05 into main Aug 6, 2026
11 checks passed
@pcarrier
pcarrier deleted the eng/lsp-drop-reap-backstop branch August 6, 2026 03:19
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Coverage

Crate Lines Functions Regions
alacritty-driver 72.7% (806/1109) 75.0% (63/84) 76.2% (1310/1719)
browser 0.0% (0/822) 0.0% (0/68) 0.0% (0/1401)
cli 24.9% (2436/9801) 36.4% (300/825) 27.5% (4128/15020)
compositor 12.2% (1221/9999) 22.8% (111/487) 12.3% (1651/13411)
fonts 81.4% (721/886) 88.6% (70/79) 83.0% (1427/1719)
fssync 92.5% (4881/5274) 94.1% (445/473) 92.5% (8927/9647)
gateway 25.5% (375/1469) 29.9% (38/127) 19.2% (470/2448)
git 87.4% (4187/4793) 88.3% (331/375) 87.0% (6625/7614)
lsp 76.1% (2503/3290) 78.5% (248/316) 74.0% (3886/5254)
proxy 19.2% (172/898) 20.5% (26/127) 21.0% (293/1392)
remote 90.3% (9306/10302) 93.2% (681/731) 88.5% (15677/17723)
sd-notify 73.9% (68/92) 100.0% (6/6) 83.2% (109/131)
server 40.5% (7873/19456) 55.1% (780/1416) 43.1% (13322/30945)
ssh 32.2% (165/512) 48.2% (27/56) 31.4% (261/830)
upsidedown 31.4% (391/1247) 27.8% (55/198) 34.8% (797/2287)
webrtc-forwarder 2.7% (72/2624) 2.1% (4/187) 1.2% (50/4335)
webserver 62.1% (1133/1825) 65.9% (164/249) 64.5% (1912/2964)
Total 48.8% (36310/74399) 57.7% (3349/5804) 51.2% (60845/118840)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant