From 9293dacc29586db5b2da870249c20a7cd925d910 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Fri, 21 Aug 2026 02:15:58 -0700 Subject: [PATCH] docs(windows): record the unsynchronised node-pty baton table Pre-existing upstream -- the exit thread erases while the main thread reads -- but terminatePtyJob adds an instance of it, so it belongs in writing rather than in someone's head. --- docs/reference/windows-process-enumeration.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/reference/windows-process-enumeration.md b/docs/reference/windows-process-enumeration.md index a96bb9955bf..ceacb109eff 100644 --- a/docs/reference/windows-process-enumeration.md +++ b/docs/reference/windows-process-enumeration.md @@ -127,3 +127,17 @@ pty has no job — an outer job without `JOB_OBJECT_LIMIT_BREAKAWAY_OK` (some ED and container hosts) can refuse the assignment, and a pty started before this build has none. Callers must fall back, not conclude the tree is gone. That conflation is the original bug. + +### Known limitation: the baton table is not synchronised + +node-pty keeps its per-terminal handles in a plain `std::vector` and erases from +it on a detached exit thread, while `get_pty_baton` is called from the main JS +thread. That race predates this change — `PtyResize`, `PtyClear` and `PtyKill` +all read the table the same way — but `terminatePtyJob` adds an instance of it: +the exit thread can close `hJob` between the lookup and `TerminateJobObject`. + +Losing that race normally just returns `FALSE`, which surfaces as `unavailable` +and falls back. The case that would not be benign is a recycled `HANDLE` value, +where the call could reach a different job in the same process. Fixing it +properly means synchronising node-pty's handle table rather than adding a lock +around one accessor, so it is deliberately left alone here.