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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! Async sockets on a [`Runtime`].
//!
//! The module has TCP sockets (`TcpListener` and `TcpStream`), a UDP socket (`UdpSocket`) and, on
//! unix platforms, unix-domain sockets in the `unix` module (`UnixListener`, `UnixStream` and
//! `UnixDatagram`). The families are behind the `tcp`, `udp` and `unix` cargo features, none on by
//! default.
//!
//! # The runtime
//!
//! A socket is created on a runtime. Its constructor takes the runtime as the first argument, and
//! the runtime's reactor watches the socket from then on.
//!
//! The socket's operations make progress while a thread is running [`Runtime::block_on`] on that
//! runtime. A runtime from `SharedRuntime::current` also has a helper thread, which drives the
//! runtime when no thread is running `block_on` on it.
//!
//! The socket's type carries the flavour of its runtime. A socket made on a [`LocalRuntime`] is,
//! for example, a `TcpStream<Local>` (`Local` is the default). It stays on the thread that made it.
//! A socket made on a [`SharedRuntime`] is a `TcpStream<Shared>`. It can be sent to and used from
//! any thread.
//!
//! # Operations
//!
//! Sockets are in non-blocking mode. When an operation would block, the task waits until the
//! runtime reports the socket ready, and other tasks run on the thread in the meantime. Connecting
//! is such an operation too, so `connect` never blocks the thread.
//!
//! TCP and UDP sockets are bound or connected to a socket address, never to a host name. Looking up
//! a name, for example with std's `ToSocketAddrs`, blocks the thread until the resolver answers,
//! and a task must not do that. To connect to a host name, look it up on another thread (for
//! example with `unblock`), then try the addresses it returns in turn.
//!
//! `TcpStream` and `UnixStream` implement the `AsyncRead` and `AsyncWrite` traits of
//! [`futures-io`], so the extension traits of [`futures`] work on them. A shared reference to a
//! stream implements the traits too, so a reader and a writer can share one stream. Closing a
//! stream shuts down its write half, and the peer then reads the end of the stream.
//!
//! # Several tasks on one socket
//!
//! Any number of tasks can wait in the async methods of one socket at once, through shared
//! references. These are the methods that accept, peek, receive or send, in either direction. When
//! the socket becomes ready, the waiting tasks wake. A task that finds another task took the data
//! first waits again.
//!
//! Two paths allow only one waiting task per direction: the `AsyncRead` and `AsyncWrite`
//! implementations of a stream, and the `Incoming` stream of a listener. If a second task waits in
//! the same direction through one of them, it replaces the first, which is then never woken. Tasks
//! that share a direction there must take turns, for example behind a lock. A task waiting in an
//! async method never replaces a task waiting through one of these paths, nor the other way round.
//!
//! # Limits on Windows
//!
//! On Windows, a runtime watches at most 1023 sockets at a time. A server there can hold at most
//! that many sockets on one runtime, its listener included.
//!
//! [`futures-io`]: https://docs.rs/futures-io
//! [`futures`]: https://docs.rs/futures
//! [`LocalRuntime`]: crate::LocalRuntime
//! [`Runtime`]: crate::Runtime
//! [`Runtime::block_on`]: crate::Runtime::block_on
//! [`SharedRuntime`]: crate::SharedRuntime
use io;
use AsFd as AsSource;
use AsSocket as AsSource;
pub use ;
pub use UdpSocket;
/// Makes a write to `socket`, once its peer has gone, fail rather than raise `SIGPIPE`, on
/// Apple's platforms, and does nothing elsewhere.
///
/// Those platforms have no `MSG_NOSIGNAL` for a write to ask for that with, so the socket sees to
/// it itself, through its `SO_NOSIGPIPE` option. std and socket2 set the option on the sockets
/// they make, but std's `pair` sets it on neither socket, and a socket handed to a `from_std` may
/// come from elsewhere.
pub