Skip to main content

Module pty

Module pty 

Source
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_TIMEOUT after FLUSHER_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 its JoinHandle would 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 mirrored persistent/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. Unlike persistent/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 separate spawn_blocking doing a raw, blocking, un-cancellable OS read()) 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 later blocking_send find the receiver gone and silently drop it, permanently losing any further output from a still-live descendant. Letting the JoinHandle simply 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_BYTES only 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 large cat) 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 via blocking_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. yes piped 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_opts payload.