nuclei/net/stream.rs
1//! The byte streams' calls, on the handle and on a shared reference to it:
2//! `AsyncRead` and `AsyncWrite`, the reads and writes that lend the driver
3//! a buffer of the caller's (and for TCP, the zero-copy write), readiness,
4//! the reads and writes that do not wait, and a stream's halves. A read
5//! side, a write side and a stream (both, with its halves) each have their
6//! macro: a socket stream takes all three, a pipe's end one side.
7//!
8//! Ready means the handle's own buffers: readable once a read would end at
9//! once (bytes read ahead, the end of the stream, or an error, which the
10//! read reports), writable once a write would be taken at once (room in the
11//! write-behind, or an error).
12
13use core::pin::Pin;
14use core::task::{Context, Poll};
15use std::io;
16use std::net::TcpStream;
17#[cfg(unix)]
18use std::os::unix::net::UnixStream;
19use std::sync::Arc;
20
21use futures_io::{AsyncRead, AsyncWrite};
22
23use super::Released;
24use super::split::{OwnedReadHalf, OwnedWriteHalf, ReadHalf, WriteHalf};
25use crate::buf::owned::{IoBuf, IoBufMut, OwnedBuf};
26use crate::buf::vectored::{self, IoVecBuf, IoVecBufMut};
27use crate::io::{Handle, Interest, Ready};
28
29/// The read side of a byte stream handle.
30macro_rules! read_side {
31 ($($ty:ty),* $(,)?) => {$(
32 impl Handle<$ty> {
33 /// Reads into the spare capacity of `buf`, after the bytes it
34 /// holds, and gives `buf` back with how many bytes came: zero at
35 /// the end of the stream, or when `buf` has no spare capacity.
36 /// The driver reads into `buf` itself, so the bytes are never
37 /// copied.
38 ///
39 /// If the future is dropped before it completes, bytes the
40 /// driver read into `buf` stay with the handle for its next
41 /// read, so none is lost. `buf` is any
42 /// [`IoBufMut`](crate::io::IoBufMut).
43 pub async fn read_owned<B>(&self, buf: B) -> (io::Result<usize>, B)
44 where
45 B: IoBufMut,
46 {
47 self.source().read_owned(buf).await
48 }
49
50 /// Reads into the spare capacity of `bufs`, after the bytes each
51 /// holds, filling each buffer's room before the next one's, and
52 /// gives `bufs` back with how many bytes came: zero at the end of
53 /// the stream, or when no buffer has spare capacity. One read of
54 /// the kernel takes every room at once (`readv`, a `recvmsg` of
55 /// several buffers, a `WSARecv` of several `WSABUF`s), as
56 /// [`read_owned`](Self::read_owned) lends one buffer: the bytes
57 /// land in the buffers themselves, never copied. Bytes another
58 /// read left behind are copied in instead, in the same order.
59 pub async fn read_vectored_owned<V>(&self, bufs: V) -> (io::Result<usize>, V)
60 where
61 V: IoVecBufMut,
62 {
63 let bufs = OwnedBuf::vectored_read(vectored::filled(bufs));
64 let (result, bufs) = self.source().read_owned(bufs).await;
65 (result, vectored::into_filled(bufs.into_segments()))
66 }
67
68 /// Waits until a read would end at once.
69 ///
70 /// # Errors
71 ///
72 /// When the stream cannot be watched.
73 pub async fn readable(&self) -> io::Result<()> {
74 core::future::poll_fn(|cx| self.poll_read_ready(cx)).await
75 }
76
77 /// Polls until a read would end at once.
78 ///
79 /// # Errors
80 ///
81 /// When the stream cannot be watched.
82 pub fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
83 self.source().poll_read_ready(cx).map(|r| r.map(drop))
84 }
85
86 /// Reads what came ahead into `buf` without waiting; zero at the
87 /// end of the stream.
88 ///
89 /// # Errors
90 ///
91 /// `WouldBlock` when nothing came yet (the driver goes on reading,
92 /// so a later call finds what comes), and as `read(2)`.
93 pub fn try_read(&self, buf: &mut [u8]) -> io::Result<usize> {
94 super::at_once(|cx| self.source().poll_read(cx, buf, false))
95 }
96
97 /// Reads what came ahead into `bufs` without waiting, as
98 /// [`try_read`](Self::try_read).
99 ///
100 /// # Errors
101 ///
102 /// As [`try_read`](Self::try_read).
103 pub fn try_read_vectored(&self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
104 super::at_once(|cx| self.source().poll_read_vectored(cx, bufs))
105 }
106 }
107
108 impl AsyncRead for &Handle<$ty> {
109 #[inline]
110 fn poll_read(
111 self: Pin<&mut Self>,
112 cx: &mut Context<'_>,
113 buf: &mut [u8],
114 ) -> Poll<io::Result<usize>> {
115 self.source().poll_read(cx, buf, false)
116 }
117
118 #[inline]
119 fn poll_read_vectored(
120 self: Pin<&mut Self>,
121 cx: &mut Context<'_>,
122 bufs: &mut [io::IoSliceMut<'_>],
123 ) -> Poll<io::Result<usize>> {
124 self.source().poll_read_vectored(cx, bufs)
125 }
126 }
127
128 impl AsyncRead for Handle<$ty> {
129 #[inline]
130 fn poll_read(
131 self: Pin<&mut Self>,
132 cx: &mut Context<'_>,
133 buf: &mut [u8],
134 ) -> Poll<io::Result<usize>> {
135 self.source().poll_read(cx, buf, false)
136 }
137
138 #[inline]
139 fn poll_read_vectored(
140 self: Pin<&mut Self>,
141 cx: &mut Context<'_>,
142 bufs: &mut [io::IoSliceMut<'_>],
143 ) -> Poll<io::Result<usize>> {
144 self.source().poll_read_vectored(cx, bufs)
145 }
146 }
147 )*};
148}
149
150/// The write side of a byte stream handle.
151macro_rules! write_side {
152 ($($ty:ty),* $(,)?) => {$(
153 impl Handle<$ty> {
154 /// Writes all of `buf` and gives it back with its length. The
155 /// driver writes from `buf` itself, so the bytes are never
156 /// copied, and the write ends once the kernel took the last of
157 /// them.
158 ///
159 /// If the future is dropped before it completes, the stream
160 /// gets `buf` whole or not at all: a write none of which went
161 /// out is withdrawn, and one that started is finished by the
162 /// driver. On Windows a TCP write is always finished: there a
163 /// cancelled send may have handed bytes to the stack while it
164 /// says it took none. `buf` is any [`IoBuf`](crate::io::IoBuf).
165 pub async fn write_owned<B>(&self, buf: B) -> (io::Result<usize>, B)
166 where
167 B: IoBuf,
168 {
169 self.source().write_owned(buf).await
170 }
171
172 /// Writes all of the bytes of `bufs`, each buffer's in order, as
173 /// one write, and gives `bufs` back with how many bytes that was.
174 /// No other write of the stream comes between two of them. Each
175 /// call of the kernel takes every buffer left at once (`writev`,
176 /// a `sendmsg` of several buffers, a `WSASend` of several
177 /// `WSABUF`s), from the buffers themselves, never copied; a call
178 /// the kernel takes part of goes on from the first byte it did
179 /// not take. If the future is dropped, as with
180 /// [`write_owned`](Self::write_owned): the stream gets all of the
181 /// bytes or none of them.
182 pub async fn write_vectored_owned<V>(&self, bufs: V) -> (io::Result<usize>, V)
183 where
184 V: IoVecBuf,
185 {
186 let bufs = OwnedBuf::vectored(vectored::written(bufs));
187 let (result, bufs) = self.source().write_owned(bufs).await;
188 (result, vectored::into_written(bufs.into_segments()))
189 }
190
191 /// Waits until a write would be taken at once.
192 ///
193 /// # Errors
194 ///
195 /// When the stream cannot be watched.
196 pub async fn writable(&self) -> io::Result<()> {
197 core::future::poll_fn(|cx| self.poll_write_ready(cx)).await
198 }
199
200 /// Polls until a write would be taken at once.
201 ///
202 /// # Errors
203 ///
204 /// When the stream cannot be watched.
205 pub fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
206 self.source().poll_write_ready(cx).map(|r| r.map(drop))
207 }
208
209 /// Hands `buf` to the write-behind without waiting; returns how
210 /// many bytes it took.
211 ///
212 /// # Errors
213 ///
214 /// `WouldBlock` when the write-behind has no room, and the error
215 /// that stopped earlier bytes.
216 pub fn try_write(&self, buf: &[u8]) -> io::Result<usize> {
217 super::at_once(|cx| self.source().poll_write_behind(cx, &[io::IoSlice::new(buf)]))
218 }
219
220 /// Hands the bytes of `bufs`, in order, to the write-behind
221 /// without waiting, as [`try_write`](Self::try_write).
222 ///
223 /// # Errors
224 ///
225 /// As [`try_write`](Self::try_write).
226 pub fn try_write_vectored(&self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
227 super::at_once(|cx| self.source().poll_write_behind(cx, bufs))
228 }
229 }
230
231 impl AsyncWrite for &Handle<$ty> {
232 #[inline]
233 fn poll_write(
234 self: Pin<&mut Self>,
235 cx: &mut Context<'_>,
236 buf: &[u8],
237 ) -> Poll<io::Result<usize>> {
238 self.source().poll_write(cx, buf)
239 }
240
241 #[inline]
242 fn poll_write_vectored(
243 self: Pin<&mut Self>,
244 cx: &mut Context<'_>,
245 bufs: &[io::IoSlice<'_>],
246 ) -> Poll<io::Result<usize>> {
247 self.source().poll_write_vectored(cx, bufs)
248 }
249
250 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
251 self.source().poll_flush(cx)
252 }
253
254 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
255 self.source().poll_close(cx)
256 }
257 }
258
259 impl AsyncWrite for Handle<$ty> {
260 #[inline]
261 fn poll_write(
262 self: Pin<&mut Self>,
263 cx: &mut Context<'_>,
264 buf: &[u8],
265 ) -> Poll<io::Result<usize>> {
266 self.source().poll_write(cx, buf)
267 }
268
269 #[inline]
270 fn poll_write_vectored(
271 self: Pin<&mut Self>,
272 cx: &mut Context<'_>,
273 bufs: &[io::IoSlice<'_>],
274 ) -> Poll<io::Result<usize>> {
275 self.source().poll_write_vectored(cx, bufs)
276 }
277
278 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
279 self.source().poll_flush(cx)
280 }
281
282 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
283 self.source().poll_close(cx)
284 }
285 }
286 )*};
287}
288
289/// A stream that both reads and writes: its readiness of either, and its
290/// halves.
291macro_rules! stream_io {
292 ($($ty:ty),* $(,)?) => {$(
293 read_side!($ty);
294 write_side!($ty);
295
296 impl Handle<$ty> {
297 /// The stream's two halves, borrowed: to read on one task and
298 /// write on another. Nothing is allocated.
299 pub fn split(&self) -> (ReadHalf<'_, $ty>, WriteHalf<'_, $ty>) {
300 (ReadHalf(self), WriteHalf(self))
301 }
302
303 /// The stream's two halves, owning it together; see
304 /// [`OwnedReadHalf::reunite`].
305 pub fn into_split(self) -> (OwnedReadHalf<$ty>, OwnedWriteHalf<$ty>) {
306 let both = Arc::new(self);
307 (OwnedReadHalf(Arc::clone(&both)), OwnedWriteHalf(both))
308 }
309
310 /// Waits until some of `interest` is ready, and says what is.
311 ///
312 /// # Errors
313 ///
314 /// When the stream cannot be watched.
315 pub async fn ready(&self, interest: Interest) -> io::Result<Ready> {
316 core::future::poll_fn(|cx| super::poll_ready(self.source(), cx, interest)).await
317 }
318 }
319 )*};
320}
321
322stream_io!(TcpStream);
323
324impl Handle<TcpStream> {
325 /// Writes all of `buf` as [`write_owned`](Self::write_owned) does, with the kernel's
326 /// zero-copy send where it has one, and returns the write's result with a [`Released`] that
327 /// gives `buf` back once the kernel let go of it.
328 ///
329 /// The write ends once the kernel took the last byte, as `write_owned`'s does, but the kernel
330 /// keeps reading `buf` until the peer acknowledged every byte; only then does the `Released`
331 /// resolve to it. So a peer that writes before it reads cannot hold the write up, and writes
332 /// pipeline: the next one may start while earlier buffers are still out.
333 ///
334 /// A write of less than the runtime's
335 /// [`zero_copy_threshold`](crate::runtime::Builder::zero_copy_threshold) (1 MiB by default),
336 /// where copying costs less, and every write on epoll, kqueue,
337 /// I/O completion ports or an io_uring kernel without zero-copy sends (or without memory it
338 /// may lock for them), is copied by the kernel as `write_owned`'s is, and its `Released` is
339 /// ready at once. So is a write served by a ring only its own thread may reap: a thread's own
340 /// shard (a stream polled by `block_on` outside the runtime's workers), or the workers of a
341 /// runtime built with [`handoff_after(None)`](crate::runtime::Builder::handoff_after). Their
342 /// rings could not be handed to another thread, which a buffer still out when the thread
343 /// stops would need.
344 ///
345 /// If the future is dropped before it completes, the stream gets `buf` whole or not at all,
346 /// as with `write_owned`. Either way `buf` is dropped only once the kernel let go of it. `buf`
347 /// is any [`IoBuf`](crate::io::IoBuf).
348 pub async fn write_zero_copy<B>(&self, buf: B) -> (io::Result<usize>, Released<B>)
349 where
350 B: IoBuf,
351 {
352 self.source().write_zero_copy(buf).await
353 }
354}
355#[cfg(unix)]
356stream_io!(UnixStream);
357#[cfg(unix)]
358read_side!(std::io::PipeReader);
359#[cfg(unix)]
360write_side!(std::io::PipeWriter);