Skip to main content

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);