Expand description
PTY geometry resolution and platform-specific shell detection.
Constants§
- FLUSHER_
BARRIER_ 🔒TIMEOUT - Budget for the fallback flush barrier. Deliberately the REMAINDER of
FLUSHER_DRAIN_TIMEOUTafterFLUSHER_EOF_GRACE, so the two waits split one budget instead of each claiming a full one — the worst-case exit delay is unchanged from before the barrier existed, rather than doubled (muxreview P2 on PR #3261). - FLUSHER_
DRAIN_ 🔒TIMEOUT - Bound on how long the wait task waits for the coalescing flusher to
drain trailing output after the direct child has already been reaped
(codex P1 on PR #3206, third round). Normally resolves almost
immediately: the read loop observes real PTY EOF once the direct child
exits and drops
pty_tx, closing the flusher’s channel. But EOF depends on every process holding the PTY slave fd closing it, not just the direct child — a background descendant that inherited the fd and ignores SIGHUP can keep it open indefinitely, in which case the flusher would never see its channel close and itsJoinHandlewould never resolve on its own. An unbounded await here would then hang child reaping’s own downstream cleanup (STATUS_DONE, run_lock release) forever, for a case that must never block them. The original 10s mirroredpersistent/process_waiter.rs’s stdout-reader bound for the same descendant-held-descriptor scenario: generous enough that normal flushing (one already-queued drain plus a write, milliseconds) never trips it, but a hard ceiling so a genuinely stuck descendant can’t hang pane teardown. Unlikepersistent/process_waiter.rs’s bound, expiry does NOT abort the flusher (reagentx P1 on PR #3206, same round): there, one combined async reader task both reads and processes, so aborting it genuinely stops the read. Here reading (a separatespawn_blockingdoing a raw, blocking, un-cancellable OSread()) and flushing are two different tasks — aborting only the flusher can’t reclaim the read loop’s thread either way, and would additionally make every laterblocking_sendfind the receiver gone and silently drop it, permanently losing any further output from a still-live descendant. Letting theJoinHandlesimply drop on timeout detaches the flusher (and transitively its read loop) to keep running independently in the background instead, so nothing produced after teardown gives up waiting is silently lost. - FLUSHER_
EOF_ 🔒GRACE - How long to wait for the STRONG completion signal — the flusher task ending, which means the read loop saw true EOF and every byte the child produced is committed — before falling back to the bounded flush barrier.
- PTY_
CHANNEL_ 🔒CAPACITY - Capacity of the channel handing PTY-read chunks from the blocking read
loop to the async coalescing flusher (reagentx P1 on PR #3206).
PTY_COALESCE_MAX_BYTESonly bounds the batch currently being assembled — it does nothing about chunks still sitting in the channel if the flusher falls behind the read rate (slow disk, lock contention, several busy panes at once). An unbounded channel there would let a sustained fast producer (yes, a largecat) grow queued memory without limit. 128 chunks x up to ~PTY_READ_BUF_SIZE each is ~512KiB of worst-case queued-but-not-yet-batched data per pane — real headroom above one coalesced batch, but strictly bounded. The read loop sends viablocking_send, which blocks the calling (already-blocking-pool) thread once the channel is full, propagating real backpressure to the PTY read rate — and from there, via the kernel’s own PTY buffer, to the child process itself, the same way a slow terminal reader naturally backpressures a fast writer. - PTY_
COALESCE_ 🔒MAX_ BYTES - Hard cap on how many bytes one coalesced batch accumulates before it is
flushed regardless of the time window — bounds both broadcast latency and
memory during a sustained, very fast burst (e.g.
yespiped through a shell pane). 64x a single PTY_READ_BUF_SIZE read: generous headroom for real bursts (a build’s stdout in a 20ms window) while still bounded. - PTY_
READ_ 🔒BUF_ SIZE - PTY read buffer size (matches Go’s 4096).
Functions§
- pty_
size_ 🔒from_ rt_ opts - Resolve the initial PTY geometry from the resync
rt_optspayload.