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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
pub use ;
use ;
/// Named pipe stream, created by a server-side listener or by connecting to a server.
///
/// This type combines in itself all possible combinations of
/// [receive modes and send modes](pipe_mode), plugged into it using the `Rm` and `Sm` generic
/// parameters respectively.
///
/// Pipe streams can be split by reference and by value for concurrent receive and send operations.
/// Splitting by reference is ephemeral and can be achieved by simply borrowing the stream, since
/// both `PipeStream` and `&PipeStream` implement I/O traits. Splitting by value is done using the
/// [`.split()`](Self::split) method, producing a receive half and a send half, and can be reverted
/// via [`.reunite()`](PipeStream::reunite).
///
/// # Additional features
/// This section documents behavior introduced by this named pipe implementation which is not
/// present in the underlying Windows API.
///
/// ## Connection termination condition thunking
/// `ERROR_PIPE_NOT_CONNECTED` and [`BrokenPipe`](std::io::ErrorKind::BrokenPipe) errors are
/// translated to EOF (`Ok(0)`) for bytestreams and `RecvResult::EndOfStream` for message streams.
///
/// ## Flushing behavior
/// Upon being dropped, streams that haven't been flushed since the last send are transparently sent
/// to **limbo** – a thread pool that ensures that the peer does not get `BrokenPipe`/EOF
/// immediately after all data has been sent, which would otherwise discard everything. Named pipe
/// handles on this thread pool are flushed first and only then closed, ensuring that they are only
/// destroyed when the peer is done reading them.
///
/// If a stream hasn't seen a single send since the last explicit flush by the time it is dropped,
/// it will evade limbo. This can be overriden with [`.mark_dirty()`](PipeStream::mark_dirty).
///
/// Similarly to limbo elision, explicit flushes are elided on streams that haven't sent anything
/// since the last flush – thus, the second of any two consecutive `.flush()` calls is a no-op that
/// returns immediately and cannot fail. This can also be overridden in the same manner.
///
/// # Examples
///
/// ## Basic bytestream client
/// ```no_run
/// ```
///
/// ## Basic message stream client
/// ```no_run
/// ```
/// Type alias for a pipe stream with the same receive mode and send mode.
pub type DuplexPipeStream<M> = ;
/// Type alias for a pipe stream with a receive mode but no send mode.
///
/// This can be produced by the listener, by connecting, or by splitting.
pub type RecvPipeStream<M> = ;
/// Type alias for a pipe stream with a send mode but no receive mode.
///
/// This can be produced by the listener, by connecting, or by splitting.
pub type SendPipeStream<M> = ;
pub