1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! Bounded retention of the output channels a process that outlived its command
//! still holds.
//!
//! A command that exits while a process it started still holds the command's
//! output channel is reported as FINISHED with that leftover named and left
//! RUNNING (it was started on purpose) — so the product keeps the read end open:
//! closing it would fault the leftover on its next write (SIGPIPE on unix, a
//! broken pipe on Windows) and kill the very process the report says is still
//! running.
//!
//! A reader is retained only when the call that started it ENDS, so the set holds
//! only channels that outlived their call — the cap can never abort the reader of
//! a call still in flight. Holding a channel costs a reader task and a file
//! descriptor, so the number held at once is bounded: past
//! [`MAX_RETAINED_CHANNELS`] the OLDEST is released (its reader aborted), which
//! closes that read end — a leftover whose next write hits the closed pipe can
//! then be terminated by the platform (SIGPIPE on unix, a broken pipe on Windows).
//! The newest is the one kept: it is what the caller was just told about.
//!
//! So the "left running" guarantee is what the product provides while it RETAINS
//! the channel: releasing it (past the cap, or when the product stops draining)
//! ends that. The cap's bound on descriptors is real; the leftover's survival is
//! not promised past it.
//!
//! The two readers that can outlive their command both retain through here: the
//! shell's capture readers and the chrome-use CLI's output pipes.
use VecDeque;
use ;
use crateUnwrapPoison;
/// How many leftover output channels the product keeps open at once.
pub const MAX_RETAINED_CHANNELS: usize = 16;
/// The retained reader tasks, oldest first.
static RETAINED: =
new;
/// Keep a reader task draining after the call that started it has returned.
/// Readers whose channel already reached EOF are dropped first (they hold
/// nothing), then the oldest channel past [`MAX_RETAINED_CHANNELS`] is released.
pub