From 6230c48c656d160d2cc9a6cb8590b49004f99663 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Fri, 25 Jun 2021 23:34:24 +0800 Subject: [PATCH 01/11] net: allow customized I/O operations for TcpStream (#3873) --- tokio/src/net/tcp/stream.rs | 91 +++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index 0277a360d09..9a633d761c3 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -936,6 +936,97 @@ impl TcpStream { .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(bufs)) } + /// Try to call a read I/O function, clearing read readiness if `f` returns + /// `WouldBlock` + /// + /// # Return value + /// + /// This functions returns exactly the same as `f` + pub fn try_read_io(&self, f: impl FnMut() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::READABLE, f) + } + + /// Polls for read readiness. + /// + /// If the tcp stream is not currently ready for reading, this method will + /// store a clone of the `Waker` from the provided `Context`. When the tcp + /// stream becomes ready for reading, `Waker::wake` will be called on the + /// waker. + /// + /// Note that on multiple calls to `poll_read_io`, only the `Waker` from + /// the `Context` passed to the most recent call is scheduled to receive a + /// wakeup. (However, `poll_write_io` retains a second, independent waker.) + /// + /// This function is intended for cases where customized I/O operations + /// may change the readiness of the underlying socket. + /// If the `f` function returns an error `WouldBlock`, then the read + /// readiness will be cleared and returns `Poll::Pending`. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the tcp stream is not ready for reading. + /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. + /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_read_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_read_io(cx, f) + } + + /// Try to call a write I/O function, clearing write readiness if `f` returns + /// `WouldBlock` + /// + /// # Return value + /// + /// This functions returns exactly the same as `f` + pub fn try_write_io(&self, f: impl FnMut() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::WRITABLE, f) + } + + /// Polls for write readiness and then calls the `f` for writing operation. + /// + /// If the tcp stream is not currently ready for writing, this method will + /// store a clone of the `Waker` from the provided `Context`. When the tcp + /// stream becomes ready for writing, `Waker::wake` will be called on the + /// waker. + /// + /// Note that on multiple calls to `poll_write_io` only + /// the `Waker` from the `Context` passed to the most recent call is + /// scheduled to receive a wakeup. (However, `poll_read_io` retains a + /// second, independent waker.) + /// + /// This function is intended for cases where customized I/O operations + /// may change the readiness of the underlying socket. + /// If the `f` function returns an error `WouldBlock`, then the write + /// readiness will be cleared and returns `Poll::Pending`. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the tcp stream is not ready for writing. + /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. + /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_write_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_write_io(cx, f) + } + /// Receives data on the socket from the remote address to which it is /// connected, without removing that data from the queue. On success, /// returns the number of bytes peeked. From 74a349335fd63d8e701183847b609589044f43bd Mon Sep 17 00:00:00 2001 From: ty Date: Thu, 1 Jul 2021 18:11:30 +0800 Subject: [PATCH 02/11] net: refine poll_*_io documentation Co-authored-by: Alice Ryhl --- tokio/src/net/tcp/stream.rs | 41 ++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index 9a633d761c3..29145a25f20 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -936,12 +936,32 @@ impl TcpStream { .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(bufs)) } - /// Try to call a read I/O function, clearing read readiness if `f` returns - /// `WouldBlock` + /// Try to read from the socket using a user-provided IO operation. /// - /// # Return value + /// If the socket is ready for reading, the provided closure is called. The + /// closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. The return value of the closure is + /// then returned by `try_read_io`. /// - /// This functions returns exactly the same as `f` + /// If the socket is not ready for reading, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `TcpStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// + /// [`readable()`]: TcpStream::readable() + /// [`ready()`]: TcpStream::ready() pub fn try_read_io(&self, f: impl FnMut() -> io::Result) -> io::Result { self.io.registration().try_io(Interest::READABLE, f) } @@ -953,9 +973,10 @@ impl TcpStream { /// stream becomes ready for reading, `Waker::wake` will be called on the /// waker. /// - /// Note that on multiple calls to `poll_read_io`, only the `Waker` from - /// the `Context` passed to the most recent call is scheduled to receive a - /// wakeup. (However, `poll_write_io` retains a second, independent waker.) + /// Note that on multiple calls to `poll_read_io`, `poll_read`, + /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` + /// passed to the most recent call is scheduled to receive a wakeup. + /// (However, `poll_write_io` retains a second, independent waker.) /// /// This function is intended for cases where customized I/O operations /// may change the readiness of the underlying socket. @@ -966,9 +987,9 @@ impl TcpStream { /// /// The function returns: /// - /// * `Poll::Pending` if the tcp stream is not ready for reading. - /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. - /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// * `Poll::Pending` if the tcp stream is not ready for reading, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. /// /// # Errors /// From daf17d7a810067d823378c8bd745dcb385f2e795 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Thu, 1 Jul 2021 18:13:00 +0800 Subject: [PATCH 03/11] net: try_read/write_io accepts FnOnce callback --- tokio/src/net/tcp/stream.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index 29145a25f20..6cc52a14f76 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -962,7 +962,7 @@ impl TcpStream { /// /// [`readable()`]: TcpStream::readable() /// [`ready()`]: TcpStream::ready() - pub fn try_read_io(&self, f: impl FnMut() -> io::Result) -> io::Result { + pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { self.io.registration().try_io(Interest::READABLE, f) } @@ -1008,7 +1008,7 @@ impl TcpStream { /// # Return value /// /// This functions returns exactly the same as `f` - pub fn try_write_io(&self, f: impl FnMut() -> io::Result) -> io::Result { + pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { self.io.registration().try_io(Interest::WRITABLE, f) } From cef6a910e06366d5409f61a738cb43a3d5f09df3 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Thu, 1 Jul 2021 18:35:56 +0800 Subject: [PATCH 04/11] net: add try_io and poll_io for UnixStream, UnixDatagram, UdpSocket --- tokio/src/net/tcp/stream.rs | 28 +++++- tokio/src/net/udp.rs | 132 ++++++++++++++++++++++++++ tokio/src/net/unix/datagram/socket.rs | 132 ++++++++++++++++++++++++++ tokio/src/net/unix/stream.rs | 132 ++++++++++++++++++++++++++ 4 files changed, 420 insertions(+), 4 deletions(-) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index 6cc52a14f76..ca0871af2a8 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -1002,12 +1002,32 @@ impl TcpStream { self.io.registration().poll_read_io(cx, f) } - /// Try to call a write I/O function, clearing write readiness if `f` returns - /// `WouldBlock` + /// Try to write from the socket using a user-provided IO operation. /// - /// # Return value + /// If the socket is ready for writing, the provided closure is called. The + /// closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the write readiness flag is cleared. The return value of the closure is + /// then returned by `try_write_io`. + /// + /// If the socket is not ready for writing, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `TcpStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// - /// This functions returns exactly the same as `f` + /// Usually, [`writable()`] or [`ready()`] is used with this function. + /// + /// [`writable()`]: TcpStream::writable() + /// [`ready()`]: TcpStream::ready() pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { self.io.registration().try_io(Interest::WRITABLE, f) } diff --git a/tokio/src/net/udp.rs b/tokio/src/net/udp.rs index 301a85cc06b..78d8ad74bbc 100644 --- a/tokio/src/net/udp.rs +++ b/tokio/src/net/udp.rs @@ -1170,6 +1170,138 @@ impl UdpSocket { .try_io(Interest::READABLE, || self.io.recv_from(buf)) } + /// Try to read from the socket using a user-provided IO operation. + /// + /// If the socket is ready for reading, the provided closure is called. The + /// closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. The return value of the closure is + /// then returned by `try_read_io`. + /// + /// If the socket is not ready for reading, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `UdpSocket` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// + /// [`readable()`]: UdpSocket::readable() + /// [`ready()`]: UdpSocket::ready() + pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::READABLE, f) + } + + /// Polls for read readiness. + /// + /// If the udp socket is not currently ready for reading, this method will + /// store a clone of the `Waker` from the provided `Context`. When the udp + /// socket becomes ready for reading, `Waker::wake` will be called on the + /// waker. + /// + /// Note that on multiple calls to `poll_read_io`, `poll_read`, + /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` + /// passed to the most recent call is scheduled to receive a wakeup. + /// (However, `poll_write_io` retains a second, independent waker.) + /// + /// This function is intended for cases where customized I/O operations + /// may change the readiness of the underlying socket. + /// If the `f` function returns an error `WouldBlock`, then the read + /// readiness will be cleared and returns `Poll::Pending`. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the udp socket is not ready for reading, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_read_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_read_io(cx, f) + } + + /// Try to write from the socket using a user-provided IO operation. + /// + /// If the socket is ready for writing, the provided closure is called. The + /// closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the write readiness flag is cleared. The return value of the closure is + /// then returned by `try_write_io`. + /// + /// If the socket is not ready for writing, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `UdpSocket` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// Usually, [`writable()`] or [`ready()`] is used with this function. + /// + /// [`writable()`]: UdpSocket::writable() + /// [`ready()`]: UdpSocket::ready() + pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::WRITABLE, f) + } + + /// Polls for write readiness and then calls the `f` for writing operation. + /// + /// If the udp socket is not currently ready for writing, this method will + /// store a clone of the `Waker` from the provided `Context`. When the udp + /// socket becomes ready for writing, `Waker::wake` will be called on the + /// waker. + /// + /// Note that on multiple calls to `poll_write_io` only + /// the `Waker` from the `Context` passed to the most recent call is + /// scheduled to receive a wakeup. (However, `poll_read_io` retains a + /// second, independent waker.) + /// + /// This function is intended for cases where customized I/O operations + /// may change the readiness of the underlying socket. + /// If the `f` function returns an error `WouldBlock`, then the write + /// readiness will be cleared and returns `Poll::Pending`. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the udp socket is not ready for writing. + /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. + /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_write_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_write_io(cx, f) + } + /// Receives data from the socket, without removing it from the input queue. /// On success, returns the number of bytes read and the address from whence /// the data came. diff --git a/tokio/src/net/unix/datagram/socket.rs b/tokio/src/net/unix/datagram/socket.rs index 2d2177803b1..58597ed3d16 100644 --- a/tokio/src/net/unix/datagram/socket.rs +++ b/tokio/src/net/unix/datagram/socket.rs @@ -1143,6 +1143,138 @@ impl UnixDatagram { Ok((n, SocketAddr(addr))) } + /// Try to read from the socket using a user-provided IO operation. + /// + /// If the socket is ready for reading, the provided closure is called. The + /// closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. The return value of the closure is + /// then returned by `try_read_io`. + /// + /// If the socket is not ready for reading, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `UnixDatagram` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// + /// [`readable()`]: UnixDatagram::readable() + /// [`ready()`]: UnixDatagram::ready() + pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::READABLE, f) + } + + /// Polls for read readiness. + /// + /// If the unix socket is not currently ready for reading, this method will + /// store a clone of the `Waker` from the provided `Context`. When the unix + /// socket becomes ready for reading, `Waker::wake` will be called on the + /// waker. + /// + /// Note that on multiple calls to `poll_read_io`, `poll_read`, + /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` + /// passed to the most recent call is scheduled to receive a wakeup. + /// (However, `poll_write_io` retains a second, independent waker.) + /// + /// This function is intended for cases where customized I/O operations + /// may change the readiness of the underlying socket. + /// If the `f` function returns an error `WouldBlock`, then the read + /// readiness will be cleared and returns `Poll::Pending`. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the unix socket is not ready for reading, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_read_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_read_io(cx, f) + } + + /// Try to write from the socket using a user-provided IO operation. + /// + /// If the socket is ready for writing, the provided closure is called. The + /// closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the write readiness flag is cleared. The return value of the closure is + /// then returned by `try_write_io`. + /// + /// If the socket is not ready for writing, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `UnixDatagram` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// Usually, [`writable()`] or [`ready()`] is used with this function. + /// + /// [`writable()`]: UnixDatagram::writable() + /// [`ready()`]: UnixDatagram::ready() + pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::WRITABLE, f) + } + + /// Polls for write readiness and then calls the `f` for writing operation. + /// + /// If the unix socket is not currently ready for writing, this method will + /// store a clone of the `Waker` from the provided `Context`. When the unix + /// socket becomes ready for writing, `Waker::wake` will be called on the + /// waker. + /// + /// Note that on multiple calls to `poll_write_io` only + /// the `Waker` from the `Context` passed to the most recent call is + /// scheduled to receive a wakeup. (However, `poll_read_io` retains a + /// second, independent waker.) + /// + /// This function is intended for cases where customized I/O operations + /// may change the readiness of the underlying socket. + /// If the `f` function returns an error `WouldBlock`, then the write + /// readiness will be cleared and returns `Poll::Pending`. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the unix socket is not ready for writing. + /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. + /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_write_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_write_io(cx, f) + } + /// Returns the local address that this socket is bound to. /// /// # Examples diff --git a/tokio/src/net/unix/stream.rs b/tokio/src/net/unix/stream.rs index 4baac606209..7ca39cbd828 100644 --- a/tokio/src/net/unix/stream.rs +++ b/tokio/src/net/unix/stream.rs @@ -653,6 +653,138 @@ impl UnixStream { .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(buf)) } + /// Try to read from the socket using a user-provided IO operation. + /// + /// If the socket is ready for reading, the provided closure is called. The + /// closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. The return value of the closure is + /// then returned by `try_read_io`. + /// + /// If the socket is not ready for reading, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `UnixStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// + /// [`readable()`]: UnixStream::readable() + /// [`ready()`]: UnixStream::ready() + pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::READABLE, f) + } + + /// Polls for read readiness. + /// + /// If the unix stream is not currently ready for reading, this method will + /// store a clone of the `Waker` from the provided `Context`. When the unix + /// stream becomes ready for reading, `Waker::wake` will be called on the + /// waker. + /// + /// Note that on multiple calls to `poll_read_io`, `poll_read`, + /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` + /// passed to the most recent call is scheduled to receive a wakeup. + /// (However, `poll_write_io` retains a second, independent waker.) + /// + /// This function is intended for cases where customized I/O operations + /// may change the readiness of the underlying socket. + /// If the `f` function returns an error `WouldBlock`, then the read + /// readiness will be cleared and returns `Poll::Pending`. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the unix stream is not ready for reading, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_read_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_read_io(cx, f) + } + + /// Try to write from the socket using a user-provided IO operation. + /// + /// If the socket is ready for writing, the provided closure is called. The + /// closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the write readiness flag is cleared. The return value of the closure is + /// then returned by `try_write_io`. + /// + /// If the socket is not ready for writing, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `UnixStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// Usually, [`writable()`] or [`ready()`] is used with this function. + /// + /// [`writable()`]: UnixStream::writable() + /// [`ready()`]: UnixStream::ready() + pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::WRITABLE, f) + } + + /// Polls for write readiness and then calls the `f` for writing operation. + /// + /// If the unix stream is not currently ready for writing, this method will + /// store a clone of the `Waker` from the provided `Context`. When the unix + /// stream becomes ready for writing, `Waker::wake` will be called on the + /// waker. + /// + /// Note that on multiple calls to `poll_write_io` only + /// the `Waker` from the `Context` passed to the most recent call is + /// scheduled to receive a wakeup. (However, `poll_read_io` retains a + /// second, independent waker.) + /// + /// This function is intended for cases where customized I/O operations + /// may change the readiness of the underlying socket. + /// If the `f` function returns an error `WouldBlock`, then the write + /// readiness will be cleared and returns `Poll::Pending`. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the unix stream is not ready for writing. + /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. + /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_write_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_write_io(cx, f) + } + /// Creates new `UnixStream` from a `std::os::unix::net::UnixStream`. /// /// This function is intended to be used to wrap a UnixStream from the From a7c21047ac20d853eb4f8f5f23a1d6fe56e14913 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Thu, 1 Jul 2021 18:59:18 +0800 Subject: [PATCH 05/11] net: updated poll_read_io and poll_write_io doc --- tokio/src/net/tcp/stream.rs | 44 +++++++++++++++++++++------ tokio/src/net/udp.rs | 44 +++++++++++++++++++++------ tokio/src/net/unix/datagram/socket.rs | 44 +++++++++++++++++++++------ tokio/src/net/unix/stream.rs | 44 +++++++++++++++++++++------ 4 files changed, 136 insertions(+), 40 deletions(-) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index ca0871af2a8..e89f30126f1 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -966,22 +966,34 @@ impl TcpStream { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read readiness. + /// Polls for read from the socket using a user-provided IO operation. /// /// If the tcp stream is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the tcp /// stream becomes ready for reading, `Waker::wake` will be called on the /// waker. /// + /// If the tcp stream is ready for reading, the provided closure is called. + /// The closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for reading. + /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` /// passed to the most recent call is scheduled to receive a wakeup. /// (However, `poll_write_io` retains a second, independent waker.) /// - /// This function is intended for cases where customized I/O operations - /// may change the readiness of the underlying socket. - /// If the `f` function returns an error `WouldBlock`, then the read - /// readiness will be cleared and returns `Poll::Pending`. + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `TcpStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// @@ -1032,22 +1044,34 @@ impl TcpStream { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write readiness and then calls the `f` for writing operation. + /// Polls for write from the socket using a user-provided IO operation. /// /// If the tcp stream is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the tcp /// stream becomes ready for writing, `Waker::wake` will be called on the /// waker. /// + /// If the tcp stream is ready for writing, the provided closure is called. + /// The closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for writing. + /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is /// scheduled to receive a wakeup. (However, `poll_read_io` retains a /// second, independent waker.) /// - /// This function is intended for cases where customized I/O operations - /// may change the readiness of the underlying socket. - /// If the `f` function returns an error `WouldBlock`, then the write - /// readiness will be cleared and returns `Poll::Pending`. + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `TcpStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// diff --git a/tokio/src/net/udp.rs b/tokio/src/net/udp.rs index 78d8ad74bbc..00595fa7a4e 100644 --- a/tokio/src/net/udp.rs +++ b/tokio/src/net/udp.rs @@ -1200,22 +1200,34 @@ impl UdpSocket { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read readiness. + /// Polls for read from the socket using a user-provided IO operation. /// /// If the udp socket is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the udp /// socket becomes ready for reading, `Waker::wake` will be called on the /// waker. /// + /// If the udp socket is ready for reading, the provided closure is called. + /// The closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for reading. + /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` /// passed to the most recent call is scheduled to receive a wakeup. /// (However, `poll_write_io` retains a second, independent waker.) /// - /// This function is intended for cases where customized I/O operations - /// may change the readiness of the underlying socket. - /// If the `f` function returns an error `WouldBlock`, then the read - /// readiness will be cleared and returns `Poll::Pending`. + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `UdpSocket` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// @@ -1266,22 +1278,34 @@ impl UdpSocket { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write readiness and then calls the `f` for writing operation. + /// Polls for write from the socket using a user-provided IO operation. /// /// If the udp socket is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the udp /// socket becomes ready for writing, `Waker::wake` will be called on the /// waker. /// + /// If the udp socket is ready for writing, the provided closure is called. + /// The closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for writing. + /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is /// scheduled to receive a wakeup. (However, `poll_read_io` retains a /// second, independent waker.) /// - /// This function is intended for cases where customized I/O operations - /// may change the readiness of the underlying socket. - /// If the `f` function returns an error `WouldBlock`, then the write - /// readiness will be cleared and returns `Poll::Pending`. + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `UdpSocket` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// diff --git a/tokio/src/net/unix/datagram/socket.rs b/tokio/src/net/unix/datagram/socket.rs index 58597ed3d16..760d8193486 100644 --- a/tokio/src/net/unix/datagram/socket.rs +++ b/tokio/src/net/unix/datagram/socket.rs @@ -1173,22 +1173,34 @@ impl UnixDatagram { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read readiness. + /// Polls for read from the socket using a user-provided IO operation. /// /// If the unix socket is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the unix /// socket becomes ready for reading, `Waker::wake` will be called on the /// waker. /// + /// If the unix socket is ready for reading, the provided closure is called. + /// The closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for reading. + /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` /// passed to the most recent call is scheduled to receive a wakeup. /// (However, `poll_write_io` retains a second, independent waker.) /// - /// This function is intended for cases where customized I/O operations - /// may change the readiness of the underlying socket. - /// If the `f` function returns an error `WouldBlock`, then the read - /// readiness will be cleared and returns `Poll::Pending`. + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `UnixDatagram` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// @@ -1239,22 +1251,34 @@ impl UnixDatagram { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write readiness and then calls the `f` for writing operation. + /// Polls for write from the socket using a user-provided IO operation. /// /// If the unix socket is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the unix /// socket becomes ready for writing, `Waker::wake` will be called on the /// waker. /// + /// If the unix socket is ready for writing, the provided closure is called. + /// The closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for writing. + /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is /// scheduled to receive a wakeup. (However, `poll_read_io` retains a /// second, independent waker.) /// - /// This function is intended for cases where customized I/O operations - /// may change the readiness of the underlying socket. - /// If the `f` function returns an error `WouldBlock`, then the write - /// readiness will be cleared and returns `Poll::Pending`. + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `UnixDatagram` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// diff --git a/tokio/src/net/unix/stream.rs b/tokio/src/net/unix/stream.rs index 7ca39cbd828..2aba483a002 100644 --- a/tokio/src/net/unix/stream.rs +++ b/tokio/src/net/unix/stream.rs @@ -683,22 +683,34 @@ impl UnixStream { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read readiness. + /// Polls for read from the socket using a user-provided IO operation. /// /// If the unix stream is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the unix /// stream becomes ready for reading, `Waker::wake` will be called on the /// waker. /// + /// If the unix stream is ready for reading, the provided closure is called. + /// The closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for reading. + /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` /// passed to the most recent call is scheduled to receive a wakeup. /// (However, `poll_write_io` retains a second, independent waker.) /// - /// This function is intended for cases where customized I/O operations - /// may change the readiness of the underlying socket. - /// If the `f` function returns an error `WouldBlock`, then the read - /// readiness will be cleared and returns `Poll::Pending`. + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `UnixStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// @@ -749,22 +761,34 @@ impl UnixStream { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write readiness and then calls the `f` for writing operation. + /// Polls for write from the socket using a user-provided IO operation. /// /// If the unix stream is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the unix /// stream becomes ready for writing, `Waker::wake` will be called on the /// waker. /// + /// If the unix stream is ready for writing, the provided closure is called. + /// The closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for writing. + /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is /// scheduled to receive a wakeup. (However, `poll_read_io` retains a /// second, independent waker.) /// - /// This function is intended for cases where customized I/O operations - /// may change the readiness of the underlying socket. - /// If the `f` function returns an error `WouldBlock`, then the write - /// readiness will be cleared and returns `Poll::Pending`. + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `UnixStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// From 3bd4a85edfe0dd675cb0af1457b5f575b79a0521 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Thu, 1 Jul 2021 19:59:28 +0800 Subject: [PATCH 06/11] net: add readiness checking and try i/o methods for named pipes --- tokio/src/net/windows/named_pipe.rs | 156 ++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/tokio/src/net/windows/named_pipe.rs b/tokio/src/net/windows/named_pipe.rs index b9f7d49d789..21698a4e90f 100644 --- a/tokio/src/net/windows/named_pipe.rs +++ b/tokio/src/net/windows/named_pipe.rs @@ -1343,6 +1343,162 @@ impl NamedPipeClient { .registration() .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(buf)) } + + /// Try to read from the named pipe using a user-provided IO operation. + /// + /// If the named pipe is ready for reading, the provided closure is called. The + /// closure should attempt to read from the named pipe by manually calling the + /// appropriate syscall. If the operation fails because the named pipe is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. The return value of the closure is + /// then returned by `try_read_io`. + /// + /// If the named pipe is not ready for reading, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the named pipe that failed due to the named pipe not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the named pipe to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `NamedPipeClient` type, as this will mess with + /// the readiness flag and can cause the named pipe to behave incorrectly. + /// + /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// + /// [`readable()`]: NamedPipeClient::readable() + /// [`ready()`]: NamedPipeClient::ready() + pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::READABLE, f) + } + + /// Polls for read from the socket using a user-provided IO operation. + /// + /// If the named pipe is not currently ready for reading, this method will + /// store a clone of the `Waker` from the provided `Context`. When the named + /// pipe becomes ready for reading, `Waker::wake` will be called on the + /// waker. + /// + /// If the named pipe is ready for reading, the provided closure is called. + /// The closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for reading. + /// + /// Note that on multiple calls to `poll_read_io`, `poll_read`, + /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` + /// passed to the most recent call is scheduled to receive a wakeup. + /// (However, `poll_write_io` retains a second, independent waker.) + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `NamedPipeClient` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the named pipe is not ready for reading, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_read_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_read_io(cx, f) + } + + /// Try to write from the named pipe using a user-provided IO operation. + /// + /// If the named pipe is ready for writing, the provided closure is called. The + /// closure should attempt to write from the named pipe by manually calling the + /// appropriate syscall. If the operation fails because the named pipe is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the write readiness flag is cleared. The return value of the closure is + /// then returned by `try_write_io`. + /// + /// If the named pipe is not ready for writing, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the named pipe that failed due to the named pipe not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the named pipe to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `NamedPipeClient` type, as this will mess with + /// the readiness flag and can cause the named pipe to behave incorrectly. + /// + /// Usually, [`writable()`] or [`ready()`] is used with this function. + /// + /// [`writable()`]: NamedPipeClient::writable() + /// [`ready()`]: NamedPipeClient::ready() + pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::WRITABLE, f) + } + + /// Polls for write from the socket using a user-provided IO operation. + /// + /// If the tcp stream is not currently ready for writing, this method will + /// store a clone of the `Waker` from the provided `Context`. When the tcp + /// stream becomes ready for writing, `Waker::wake` will be called on the + /// waker. + /// + /// If the tcp stream is ready for writing, the provided closure is called. + /// The closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. Stores and wakes the clone of the + /// `Waker` just like it was not ready for writing. + /// + /// Note that on multiple calls to `poll_write_io` only + /// the `Waker` from the `Context` passed to the most recent call is + /// scheduled to receive a wakeup. (However, `poll_read_io` retains a + /// second, independent waker.) + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `TcpStream` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the tcp stream is not ready for writing. + /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. + /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_write_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_write_io(cx, f) + } } impl AsyncRead for NamedPipeClient { From 6560b257361baea97c0eade98d69f8dfb97b5895 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Thu, 1 Jul 2021 22:54:46 +0800 Subject: [PATCH 07/11] net: refine poll_read_io and poll_write_io docs --- tokio/src/net/tcp/stream.rs | 14 +- tokio/src/net/udp.rs | 14 +- tokio/src/net/unix/datagram/socket.rs | 14 +- tokio/src/net/unix/stream.rs | 14 +- tokio/src/net/windows/named_pipe.rs | 184 ++++++++++++++++++++++++-- 5 files changed, 214 insertions(+), 26 deletions(-) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index e89f30126f1..87d8ef505c8 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -977,8 +977,11 @@ impl TcpStream { /// The closure should attempt to read from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for reading. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the tcp stream becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` @@ -1055,8 +1058,11 @@ impl TcpStream { /// The closure should attempt to write from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for writing. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the tcp stream becomes ready for writing, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is diff --git a/tokio/src/net/udp.rs b/tokio/src/net/udp.rs index 00595fa7a4e..46d3259413f 100644 --- a/tokio/src/net/udp.rs +++ b/tokio/src/net/udp.rs @@ -1211,8 +1211,11 @@ impl UdpSocket { /// The closure should attempt to read from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for reading. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the udp socket becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` @@ -1289,8 +1292,11 @@ impl UdpSocket { /// The closure should attempt to write from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for writing. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the udp socket becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is diff --git a/tokio/src/net/unix/datagram/socket.rs b/tokio/src/net/unix/datagram/socket.rs index 760d8193486..cb2ff8ccabd 100644 --- a/tokio/src/net/unix/datagram/socket.rs +++ b/tokio/src/net/unix/datagram/socket.rs @@ -1184,8 +1184,11 @@ impl UnixDatagram { /// The closure should attempt to read from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for reading. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the unix socket becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` @@ -1262,8 +1265,11 @@ impl UnixDatagram { /// The closure should attempt to write from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for writing. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the unix socket becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is diff --git a/tokio/src/net/unix/stream.rs b/tokio/src/net/unix/stream.rs index 2aba483a002..ed20212b3bc 100644 --- a/tokio/src/net/unix/stream.rs +++ b/tokio/src/net/unix/stream.rs @@ -694,8 +694,11 @@ impl UnixStream { /// The closure should attempt to read from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for reading. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the unix stream becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` @@ -772,8 +775,11 @@ impl UnixStream { /// The closure should attempt to write from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for writing. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the unix stream becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is diff --git a/tokio/src/net/windows/named_pipe.rs b/tokio/src/net/windows/named_pipe.rs index 21698a4e90f..e022107efa2 100644 --- a/tokio/src/net/windows/named_pipe.rs +++ b/tokio/src/net/windows/named_pipe.rs @@ -723,6 +723,168 @@ impl NamedPipeServer { .registration() .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(buf)) } + + /// Try to read from the named pipe using a user-provided IO operation. + /// + /// If the named pipe is ready for reading, the provided closure is called. The + /// closure should attempt to read from the named pipe by manually calling the + /// appropriate syscall. If the operation fails because the named pipe is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. The return value of the closure is + /// then returned by `try_read_io`. + /// + /// If the named pipe is not ready for reading, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the named pipe that failed due to the named pipe not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the named pipe to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `NamedPipeServer` type, as this will mess with + /// the readiness flag and can cause the named pipe to behave incorrectly. + /// + /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// + /// [`readable()`]: NamedPipeServer::readable() + /// [`ready()`]: NamedPipeServer::ready() + pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::READABLE, f) + } + + /// Polls for read from the socket using a user-provided IO operation. + /// + /// If the named pipe is not currently ready for reading, this method will + /// store a clone of the `Waker` from the provided `Context`. When the named + /// pipe becomes ready for reading, `Waker::wake` will be called on the + /// waker. + /// + /// If the named pipe is ready for reading, the provided closure is called. + /// The closure should attempt to read from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. + /// + /// Note that on multiple calls to `poll_read_io`, `poll_read`, + /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` + /// passed to the most recent call is scheduled to receive a wakeup. + /// (However, `poll_write_io` retains a second, independent waker.) + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the read operation using any of the + /// methods defined on the Tokio `NamedPipeServer` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the named pipe is not ready for reading, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_read_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_read_io(cx, f) + } + + /// Try to write from the named pipe using a user-provided IO operation. + /// + /// If the named pipe is ready for writing, the provided closure is called. The + /// closure should attempt to write from the named pipe by manually calling the + /// appropriate syscall. If the operation fails because the named pipe is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the write readiness flag is cleared. The return value of the closure is + /// then returned by `try_write_io`. + /// + /// If the named pipe is not ready for writing, then the closure is not called + /// and a `WouldBlock` error is returned. + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the named pipe that failed due to the named pipe not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the named pipe to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `NamedPipeServer` type, as this will mess with + /// the readiness flag and can cause the named pipe to behave incorrectly. + /// + /// Usually, [`writable()`] or [`ready()`] is used with this function. + /// + /// [`writable()`]: NamedPipeServer::writable() + /// [`ready()`]: NamedPipeServer::ready() + pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { + self.io.registration().try_io(Interest::WRITABLE, f) + } + + /// Polls for write from the socket using a user-provided IO operation. + /// + /// If the named pipe is not currently ready for writing, this method will + /// store a clone of the `Waker` from the provided `Context`. When the named + /// pipe becomes ready for writing, `Waker::wake` will be called on the + /// waker. + /// + /// If the named pipe is ready for writing, the provided closure is called. + /// The closure should attempt to write from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not + /// actually ready, then the closure should return a `WouldBlock` error and + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` + /// will be called on the waker. The provided closure may be called multiple times + /// if the socket become ready right in the instance after the closure has returned + /// `WouldBlock`. + /// + /// Note that on multiple calls to `poll_write_io` only + /// the `Waker` from the `Context` passed to the most recent call is + /// scheduled to receive a wakeup. (However, `poll_read_io` retains a + /// second, independent waker.) + /// + /// The closure should only return a `WouldBlock` error if it has performed + /// an IO operation on the socket that failed due to the socket not being + /// ready. Returning a `WouldBlock` error in any other situation will + /// incorrectly clear the readiness flag, which can cause the socket to + /// behave incorrectly. + /// + /// The closure should not perform the write operation using any of the + /// methods defined on the Tokio `NamedPipeServer` type, as this will mess with + /// the readiness flag and can cause the socket to behave incorrectly. + /// + /// # Return value + /// + /// The function returns: + /// + /// * `Poll::Pending` if the named pipe is not ready for writing. + /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. + /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// + /// # Errors + /// + /// This function may encounter any standard I/O error except `WouldBlock`. + pub fn poll_write_io( + &self, + cx: &mut Context<'_>, + f: impl FnMut() -> io::Result, + ) -> Poll> { + self.io.registration().poll_write_io(cx, f) + } } impl AsyncRead for NamedPipeServer { @@ -1385,8 +1547,9 @@ impl NamedPipeClient { /// The closure should attempt to read from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for reading. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` + /// will be called on the waker. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` @@ -1454,17 +1617,18 @@ impl NamedPipeClient { /// Polls for write from the socket using a user-provided IO operation. /// - /// If the tcp stream is not currently ready for writing, this method will - /// store a clone of the `Waker` from the provided `Context`. When the tcp - /// stream becomes ready for writing, `Waker::wake` will be called on the + /// If the named pipe is not currently ready for writing, this method will + /// store a clone of the `Waker` from the provided `Context`. When the named + /// pipe becomes ready for writing, `Waker::wake` will be called on the /// waker. /// - /// If the tcp stream is ready for writing, the provided closure is called. + /// If the named pipe is ready for writing, the provided closure is called. /// The closure should attempt to write from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. Stores and wakes the clone of the - /// `Waker` just like it was not ready for writing. + /// the read readiness flag is cleared. The `Waker` from the provided `Context` + /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` + /// will be called on the waker. /// /// Note that on multiple calls to `poll_write_io` only /// the `Waker` from the `Context` passed to the most recent call is @@ -1478,14 +1642,14 @@ impl NamedPipeClient { /// behave incorrectly. /// /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `TcpStream` type, as this will mess with + /// methods defined on the Tokio `NamedPipeClient` type, as this will mess with /// the readiness flag and can cause the socket to behave incorrectly. /// /// # Return value /// /// The function returns: /// - /// * `Poll::Pending` if the tcp stream is not ready for writing. + /// * `Poll::Pending` if the named pipe is not ready for writing. /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. /// From 92bb3229281cc10e83906766e54237d51c5ad340 Mon Sep 17 00:00:00 2001 From: ty Date: Fri, 2 Jul 2021 23:04:23 +0800 Subject: [PATCH 08/11] net: refine docs for poll_io and try_io Co-authored-by: Alice Ryhl --- tokio/src/net/tcp/stream.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index 87d8ef505c8..9759427b267 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -966,7 +966,7 @@ impl TcpStream { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read from the socket using a user-provided IO operation. + /// Poll for read readiness, then reads from the socket using a user-provided IO operation. /// /// If the tcp stream is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the tcp @@ -980,7 +980,7 @@ impl TcpStream { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the tcp stream becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instant after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, @@ -1047,7 +1047,7 @@ impl TcpStream { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write from the socket using a user-provided IO operation. + /// Poll for write readiness, then writes to the socket using a user-provided IO operation. /// /// If the tcp stream is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the tcp @@ -1061,7 +1061,7 @@ impl TcpStream { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the tcp stream becomes ready for writing, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instant after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only @@ -1083,9 +1083,9 @@ impl TcpStream { /// /// The function returns: /// - /// * `Poll::Pending` if the tcp stream is not ready for writing. - /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. - /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// * `Poll::Pending` if the tcp stream is not ready for writing, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. /// /// # Errors /// From 74fdf09916a6ce9c2551b6b2bf97d79339943660 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Fri, 2 Jul 2021 23:11:44 +0800 Subject: [PATCH 09/11] net: applies changes to all the other structs --- tokio/src/net/udp.rs | 14 +++++++------- tokio/src/net/unix/datagram/socket.rs | 14 +++++++------- tokio/src/net/unix/stream.rs | 14 +++++++------- tokio/src/net/windows/named_pipe.rs | 24 ++++++++++++------------ 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tokio/src/net/udp.rs b/tokio/src/net/udp.rs index 46d3259413f..5834d27d97a 100644 --- a/tokio/src/net/udp.rs +++ b/tokio/src/net/udp.rs @@ -1200,7 +1200,7 @@ impl UdpSocket { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read from the socket using a user-provided IO operation. + /// Poll for read readiness, then reads from the socket using a user-provided IO operation. /// /// If the udp socket is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the udp @@ -1214,7 +1214,7 @@ impl UdpSocket { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the udp socket becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instance after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, @@ -1281,7 +1281,7 @@ impl UdpSocket { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write from the socket using a user-provided IO operation. + /// Poll for write readiness, then writes to the socket using a user-provided IO operation. /// /// If the udp socket is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the udp @@ -1295,7 +1295,7 @@ impl UdpSocket { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the udp socket becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instance after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only @@ -1317,9 +1317,9 @@ impl UdpSocket { /// /// The function returns: /// - /// * `Poll::Pending` if the udp socket is not ready for writing. - /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. - /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// * `Poll::Pending` if the udp socket is not ready for writing, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. /// /// # Errors /// diff --git a/tokio/src/net/unix/datagram/socket.rs b/tokio/src/net/unix/datagram/socket.rs index cb2ff8ccabd..a60897c403c 100644 --- a/tokio/src/net/unix/datagram/socket.rs +++ b/tokio/src/net/unix/datagram/socket.rs @@ -1173,7 +1173,7 @@ impl UnixDatagram { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read from the socket using a user-provided IO operation. + /// Poll for read readiness, then reads from the socket using a user-provided IO operation. /// /// If the unix socket is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the unix @@ -1187,7 +1187,7 @@ impl UnixDatagram { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the unix socket becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instance after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, @@ -1254,7 +1254,7 @@ impl UnixDatagram { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write from the socket using a user-provided IO operation. + /// Poll for write readiness, then writes to the socket using a user-provided IO operation. /// /// If the unix socket is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the unix @@ -1268,7 +1268,7 @@ impl UnixDatagram { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the unix socket becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instance after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only @@ -1290,9 +1290,9 @@ impl UnixDatagram { /// /// The function returns: /// - /// * `Poll::Pending` if the unix socket is not ready for writing. - /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. - /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// * `Poll::Pending` if the unix socket is not ready for writing, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. /// /// # Errors /// diff --git a/tokio/src/net/unix/stream.rs b/tokio/src/net/unix/stream.rs index ed20212b3bc..48c829c274c 100644 --- a/tokio/src/net/unix/stream.rs +++ b/tokio/src/net/unix/stream.rs @@ -683,7 +683,7 @@ impl UnixStream { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read from the socket using a user-provided IO operation. + /// Poll for read readiness, then reads from the socket using a user-provided IO operation. /// /// If the unix stream is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the unix @@ -697,7 +697,7 @@ impl UnixStream { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the unix stream becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instance after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, @@ -764,7 +764,7 @@ impl UnixStream { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write from the socket using a user-provided IO operation. + /// Poll for write readiness, then writes to the socket using a user-provided IO operation. /// /// If the unix stream is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the unix @@ -778,7 +778,7 @@ impl UnixStream { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the unix stream becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instance after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only @@ -800,9 +800,9 @@ impl UnixStream { /// /// The function returns: /// - /// * `Poll::Pending` if the unix stream is not ready for writing. - /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. - /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// * `Poll::Pending` if the unix stream is not ready for writing, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. /// /// # Errors /// diff --git a/tokio/src/net/windows/named_pipe.rs b/tokio/src/net/windows/named_pipe.rs index e022107efa2..c00904814ce 100644 --- a/tokio/src/net/windows/named_pipe.rs +++ b/tokio/src/net/windows/named_pipe.rs @@ -754,7 +754,7 @@ impl NamedPipeServer { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read from the socket using a user-provided IO operation. + /// Poll for read readiness, then reads from the socket using a user-provided IO operation. /// /// If the named pipe is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the named @@ -768,7 +768,7 @@ impl NamedPipeServer { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instance after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_read_io`, `poll_read`, @@ -835,7 +835,7 @@ impl NamedPipeServer { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write from the socket using a user-provided IO operation. + /// Poll for write readiness, then writes to the socket using a user-provided IO operation. /// /// If the named pipe is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the named @@ -849,7 +849,7 @@ impl NamedPipeServer { /// the read readiness flag is cleared. The `Waker` from the provided `Context` /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready right in the instance after the closure has returned + /// if the socket become ready in the instance after the closure has returned /// `WouldBlock`. /// /// Note that on multiple calls to `poll_write_io` only @@ -871,9 +871,9 @@ impl NamedPipeServer { /// /// The function returns: /// - /// * `Poll::Pending` if the named pipe is not ready for writing. - /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. - /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// * `Poll::Pending` if the named pipe is not ready for writing, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. /// /// # Errors /// @@ -1536,7 +1536,7 @@ impl NamedPipeClient { self.io.registration().try_io(Interest::READABLE, f) } - /// Polls for read from the socket using a user-provided IO operation. + /// Poll for read readiness, then reads from the socket using a user-provided IO operation. /// /// If the named pipe is not currently ready for reading, this method will /// store a clone of the `Waker` from the provided `Context`. When the named @@ -1615,7 +1615,7 @@ impl NamedPipeClient { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Polls for write from the socket using a user-provided IO operation. + /// Poll for write readiness, then writes to the socket using a user-provided IO operation. /// /// If the named pipe is not currently ready for writing, this method will /// store a clone of the `Waker` from the provided `Context`. When the named @@ -1649,9 +1649,9 @@ impl NamedPipeClient { /// /// The function returns: /// - /// * `Poll::Pending` if the named pipe is not ready for writing. - /// * `Poll::Ready(Ok(R))` if the `f` returns `Ok(R)`. - /// * `Poll::Ready(Err(e))` if an error is encountered from `f` except `WouldBlock`. + /// * `Poll::Pending` if the named pipe is not ready for writing, or if `f` returns a `WouldBlock` error. + /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. + /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. /// /// # Errors /// From 6fa7de17f01c761acb34fa8b62c46ce5708208f0 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Sat, 3 Jul 2021 10:39:41 +0800 Subject: [PATCH 10/11] net: removes poll_*_io prefers try_*_io --- tokio/src/net/tcp/stream.rs | 102 -------------------------- tokio/src/net/udp.rs | 102 -------------------------- tokio/src/net/unix/datagram/socket.rs | 102 -------------------------- tokio/src/net/unix/stream.rs | 102 -------------------------- tokio/src/net/windows/named_pipe.rs | 102 -------------------------- 5 files changed, 510 deletions(-) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index 9759427b267..fdf4d00fe27 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -966,57 +966,6 @@ impl TcpStream { self.io.registration().try_io(Interest::READABLE, f) } - /// Poll for read readiness, then reads from the socket using a user-provided IO operation. - /// - /// If the tcp stream is not currently ready for reading, this method will - /// store a clone of the `Waker` from the provided `Context`. When the tcp - /// stream becomes ready for reading, `Waker::wake` will be called on the - /// waker. - /// - /// If the tcp stream is ready for reading, the provided closure is called. - /// The closure should attempt to read from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the tcp stream becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instant after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_read_io`, `poll_read`, - /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` - /// passed to the most recent call is scheduled to receive a wakeup. - /// (However, `poll_write_io` retains a second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the read operation using any of the - /// methods defined on the Tokio `TcpStream` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the tcp stream is not ready for reading, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_read_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_read_io(cx, f) - } - /// Try to write from the socket using a user-provided IO operation. /// /// If the socket is ready for writing, the provided closure is called. The @@ -1047,57 +996,6 @@ impl TcpStream { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Poll for write readiness, then writes to the socket using a user-provided IO operation. - /// - /// If the tcp stream is not currently ready for writing, this method will - /// store a clone of the `Waker` from the provided `Context`. When the tcp - /// stream becomes ready for writing, `Waker::wake` will be called on the - /// waker. - /// - /// If the tcp stream is ready for writing, the provided closure is called. - /// The closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the tcp stream becomes ready for writing, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instant after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_write_io` only - /// the `Waker` from the `Context` passed to the most recent call is - /// scheduled to receive a wakeup. (However, `poll_read_io` retains a - /// second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `TcpStream` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the tcp stream is not ready for writing, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_write_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_write_io(cx, f) - } - /// Receives data on the socket from the remote address to which it is /// connected, without removing that data from the queue. On success, /// returns the number of bytes peeked. diff --git a/tokio/src/net/udp.rs b/tokio/src/net/udp.rs index 5834d27d97a..fb794c881ae 100644 --- a/tokio/src/net/udp.rs +++ b/tokio/src/net/udp.rs @@ -1200,57 +1200,6 @@ impl UdpSocket { self.io.registration().try_io(Interest::READABLE, f) } - /// Poll for read readiness, then reads from the socket using a user-provided IO operation. - /// - /// If the udp socket is not currently ready for reading, this method will - /// store a clone of the `Waker` from the provided `Context`. When the udp - /// socket becomes ready for reading, `Waker::wake` will be called on the - /// waker. - /// - /// If the udp socket is ready for reading, the provided closure is called. - /// The closure should attempt to read from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the udp socket becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instance after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_read_io`, `poll_read`, - /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` - /// passed to the most recent call is scheduled to receive a wakeup. - /// (However, `poll_write_io` retains a second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the read operation using any of the - /// methods defined on the Tokio `UdpSocket` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the udp socket is not ready for reading, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_read_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_read_io(cx, f) - } - /// Try to write from the socket using a user-provided IO operation. /// /// If the socket is ready for writing, the provided closure is called. The @@ -1281,57 +1230,6 @@ impl UdpSocket { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Poll for write readiness, then writes to the socket using a user-provided IO operation. - /// - /// If the udp socket is not currently ready for writing, this method will - /// store a clone of the `Waker` from the provided `Context`. When the udp - /// socket becomes ready for writing, `Waker::wake` will be called on the - /// waker. - /// - /// If the udp socket is ready for writing, the provided closure is called. - /// The closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the udp socket becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instance after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_write_io` only - /// the `Waker` from the `Context` passed to the most recent call is - /// scheduled to receive a wakeup. (However, `poll_read_io` retains a - /// second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `UdpSocket` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the udp socket is not ready for writing, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_write_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_write_io(cx, f) - } - /// Receives data from the socket, without removing it from the input queue. /// On success, returns the number of bytes read and the address from whence /// the data came. diff --git a/tokio/src/net/unix/datagram/socket.rs b/tokio/src/net/unix/datagram/socket.rs index a60897c403c..2153d0d71dc 100644 --- a/tokio/src/net/unix/datagram/socket.rs +++ b/tokio/src/net/unix/datagram/socket.rs @@ -1173,57 +1173,6 @@ impl UnixDatagram { self.io.registration().try_io(Interest::READABLE, f) } - /// Poll for read readiness, then reads from the socket using a user-provided IO operation. - /// - /// If the unix socket is not currently ready for reading, this method will - /// store a clone of the `Waker` from the provided `Context`. When the unix - /// socket becomes ready for reading, `Waker::wake` will be called on the - /// waker. - /// - /// If the unix socket is ready for reading, the provided closure is called. - /// The closure should attempt to read from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the unix socket becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instance after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_read_io`, `poll_read`, - /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` - /// passed to the most recent call is scheduled to receive a wakeup. - /// (However, `poll_write_io` retains a second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the read operation using any of the - /// methods defined on the Tokio `UnixDatagram` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the unix socket is not ready for reading, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_read_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_read_io(cx, f) - } - /// Try to write from the socket using a user-provided IO operation. /// /// If the socket is ready for writing, the provided closure is called. The @@ -1254,57 +1203,6 @@ impl UnixDatagram { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Poll for write readiness, then writes to the socket using a user-provided IO operation. - /// - /// If the unix socket is not currently ready for writing, this method will - /// store a clone of the `Waker` from the provided `Context`. When the unix - /// socket becomes ready for writing, `Waker::wake` will be called on the - /// waker. - /// - /// If the unix socket is ready for writing, the provided closure is called. - /// The closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the unix socket becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instance after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_write_io` only - /// the `Waker` from the `Context` passed to the most recent call is - /// scheduled to receive a wakeup. (However, `poll_read_io` retains a - /// second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `UnixDatagram` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the unix socket is not ready for writing, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_write_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_write_io(cx, f) - } - /// Returns the local address that this socket is bound to. /// /// # Examples diff --git a/tokio/src/net/unix/stream.rs b/tokio/src/net/unix/stream.rs index 48c829c274c..c4aa70df6e9 100644 --- a/tokio/src/net/unix/stream.rs +++ b/tokio/src/net/unix/stream.rs @@ -683,57 +683,6 @@ impl UnixStream { self.io.registration().try_io(Interest::READABLE, f) } - /// Poll for read readiness, then reads from the socket using a user-provided IO operation. - /// - /// If the unix stream is not currently ready for reading, this method will - /// store a clone of the `Waker` from the provided `Context`. When the unix - /// stream becomes ready for reading, `Waker::wake` will be called on the - /// waker. - /// - /// If the unix stream is ready for reading, the provided closure is called. - /// The closure should attempt to read from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the unix stream becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instance after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_read_io`, `poll_read`, - /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` - /// passed to the most recent call is scheduled to receive a wakeup. - /// (However, `poll_write_io` retains a second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the read operation using any of the - /// methods defined on the Tokio `UnixStream` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the unix stream is not ready for reading, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_read_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_read_io(cx, f) - } - /// Try to write from the socket using a user-provided IO operation. /// /// If the socket is ready for writing, the provided closure is called. The @@ -764,57 +713,6 @@ impl UnixStream { self.io.registration().try_io(Interest::WRITABLE, f) } - /// Poll for write readiness, then writes to the socket using a user-provided IO operation. - /// - /// If the unix stream is not currently ready for writing, this method will - /// store a clone of the `Waker` from the provided `Context`. When the unix - /// stream becomes ready for writing, `Waker::wake` will be called on the - /// waker. - /// - /// If the unix stream is ready for writing, the provided closure is called. - /// The closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the unix stream becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instance after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_write_io` only - /// the `Waker` from the `Context` passed to the most recent call is - /// scheduled to receive a wakeup. (However, `poll_read_io` retains a - /// second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `UnixStream` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the unix stream is not ready for writing, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_write_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_write_io(cx, f) - } - /// Creates new `UnixStream` from a `std::os::unix::net::UnixStream`. /// /// This function is intended to be used to wrap a UnixStream from the diff --git a/tokio/src/net/windows/named_pipe.rs b/tokio/src/net/windows/named_pipe.rs index c00904814ce..0a97cc3821e 100644 --- a/tokio/src/net/windows/named_pipe.rs +++ b/tokio/src/net/windows/named_pipe.rs @@ -754,57 +754,6 @@ impl NamedPipeServer { self.io.registration().try_io(Interest::READABLE, f) } - /// Poll for read readiness, then reads from the socket using a user-provided IO operation. - /// - /// If the named pipe is not currently ready for reading, this method will - /// store a clone of the `Waker` from the provided `Context`. When the named - /// pipe becomes ready for reading, `Waker::wake` will be called on the - /// waker. - /// - /// If the named pipe is ready for reading, the provided closure is called. - /// The closure should attempt to read from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instance after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_read_io`, `poll_read`, - /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` - /// passed to the most recent call is scheduled to receive a wakeup. - /// (However, `poll_write_io` retains a second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the read operation using any of the - /// methods defined on the Tokio `NamedPipeServer` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the named pipe is not ready for reading, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_read_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_read_io(cx, f) - } - /// Try to write from the named pipe using a user-provided IO operation. /// /// If the named pipe is ready for writing, the provided closure is called. The @@ -834,57 +783,6 @@ impl NamedPipeServer { pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { self.io.registration().try_io(Interest::WRITABLE, f) } - - /// Poll for write readiness, then writes to the socket using a user-provided IO operation. - /// - /// If the named pipe is not currently ready for writing, this method will - /// store a clone of the `Waker` from the provided `Context`. When the named - /// pipe becomes ready for writing, `Waker::wake` will be called on the - /// waker. - /// - /// If the named pipe is ready for writing, the provided closure is called. - /// The closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` - /// will be called on the waker. The provided closure may be called multiple times - /// if the socket become ready in the instance after the closure has returned - /// `WouldBlock`. - /// - /// Note that on multiple calls to `poll_write_io` only - /// the `Waker` from the `Context` passed to the most recent call is - /// scheduled to receive a wakeup. (However, `poll_read_io` retains a - /// second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `NamedPipeServer` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the named pipe is not ready for writing, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_write_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_write_io(cx, f) - } } impl AsyncRead for NamedPipeServer { From 279c0ef3407bcf4e393183f75ba1c5927061c514 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Thu, 8 Jul 2021 10:10:24 +0800 Subject: [PATCH 11/11] net: merge try_read_io and try_write_io to try_io --- tokio/src/net/tcp/stream.rs | 51 ++----- tokio/src/net/udp.rs | 51 ++----- tokio/src/net/unix/datagram/socket.rs | 51 ++----- tokio/src/net/unix/stream.rs | 51 ++----- tokio/src/net/windows/named_pipe.rs | 210 ++++---------------------- 5 files changed, 83 insertions(+), 331 deletions(-) diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index fdf4d00fe27..daf3dccde7f 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -936,16 +936,16 @@ impl TcpStream { .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(bufs)) } - /// Try to read from the socket using a user-provided IO operation. + /// Try to perform IO operation from the socket using a user-provided IO operation. /// - /// If the socket is ready for reading, the provided closure is called. The - /// closure should attempt to read from the socket by manually calling the + /// If the socket is ready, the provided closure is called. The + /// closure should attempt to perform IO operation from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The return value of the closure is - /// then returned by `try_read_io`. + /// the readiness flag is cleared. The return value of the closure is + /// then returned by `try_io`. /// - /// If the socket is not ready for reading, then the closure is not called + /// If the socket is not ready, then the closure is not called /// and a `WouldBlock` error is returned. /// /// The closure should only return a `WouldBlock` error if it has performed @@ -958,42 +958,17 @@ impl TcpStream { /// methods defined on the Tokio `TcpStream` type, as this will mess with /// the readiness flag and can cause the socket to behave incorrectly. /// - /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// Usually, [`readable()`], [`writable()`] or [`ready()`] is used with this function. /// /// [`readable()`]: TcpStream::readable() - /// [`ready()`]: TcpStream::ready() - pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::READABLE, f) - } - - /// Try to write from the socket using a user-provided IO operation. - /// - /// If the socket is ready for writing, the provided closure is called. The - /// closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the write readiness flag is cleared. The return value of the closure is - /// then returned by `try_write_io`. - /// - /// If the socket is not ready for writing, then the closure is not called - /// and a `WouldBlock` error is returned. - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `TcpStream` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// Usually, [`writable()`] or [`ready()`] is used with this function. - /// /// [`writable()`]: TcpStream::writable() /// [`ready()`]: TcpStream::ready() - pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::WRITABLE, f) + pub fn try_io( + &self, + interest: Interest, + f: impl FnOnce() -> io::Result, + ) -> io::Result { + self.io.registration().try_io(interest, f) } /// Receives data on the socket from the remote address to which it is diff --git a/tokio/src/net/udp.rs b/tokio/src/net/udp.rs index fb794c881ae..a47f071d770 100644 --- a/tokio/src/net/udp.rs +++ b/tokio/src/net/udp.rs @@ -1170,16 +1170,16 @@ impl UdpSocket { .try_io(Interest::READABLE, || self.io.recv_from(buf)) } - /// Try to read from the socket using a user-provided IO operation. + /// Try to perform IO operation from the socket using a user-provided IO operation. /// - /// If the socket is ready for reading, the provided closure is called. The - /// closure should attempt to read from the socket by manually calling the + /// If the socket is ready, the provided closure is called. The + /// closure should attempt to perform IO operation from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The return value of the closure is - /// then returned by `try_read_io`. + /// the readiness flag is cleared. The return value of the closure is + /// then returned by `try_io`. /// - /// If the socket is not ready for reading, then the closure is not called + /// If the socket is not ready, then the closure is not called /// and a `WouldBlock` error is returned. /// /// The closure should only return a `WouldBlock` error if it has performed @@ -1192,42 +1192,17 @@ impl UdpSocket { /// methods defined on the Tokio `UdpSocket` type, as this will mess with /// the readiness flag and can cause the socket to behave incorrectly. /// - /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// Usually, [`readable()`], [`writable()`] or [`ready()`] is used with this function. /// /// [`readable()`]: UdpSocket::readable() - /// [`ready()`]: UdpSocket::ready() - pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::READABLE, f) - } - - /// Try to write from the socket using a user-provided IO operation. - /// - /// If the socket is ready for writing, the provided closure is called. The - /// closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the write readiness flag is cleared. The return value of the closure is - /// then returned by `try_write_io`. - /// - /// If the socket is not ready for writing, then the closure is not called - /// and a `WouldBlock` error is returned. - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `UdpSocket` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// Usually, [`writable()`] or [`ready()`] is used with this function. - /// /// [`writable()`]: UdpSocket::writable() /// [`ready()`]: UdpSocket::ready() - pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::WRITABLE, f) + pub fn try_io( + &self, + interest: Interest, + f: impl FnOnce() -> io::Result, + ) -> io::Result { + self.io.registration().try_io(interest, f) } /// Receives data from the socket, without removing it from the input queue. diff --git a/tokio/src/net/unix/datagram/socket.rs b/tokio/src/net/unix/datagram/socket.rs index 2153d0d71dc..c7c6568f21e 100644 --- a/tokio/src/net/unix/datagram/socket.rs +++ b/tokio/src/net/unix/datagram/socket.rs @@ -1143,16 +1143,16 @@ impl UnixDatagram { Ok((n, SocketAddr(addr))) } - /// Try to read from the socket using a user-provided IO operation. + /// Try to perform IO operation from the socket using a user-provided IO operation. /// - /// If the socket is ready for reading, the provided closure is called. The - /// closure should attempt to read from the socket by manually calling the + /// If the socket is ready, the provided closure is called. The + /// closure should attempt to perform IO operation from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The return value of the closure is - /// then returned by `try_read_io`. + /// the readiness flag is cleared. The return value of the closure is + /// then returned by `try_io`. /// - /// If the socket is not ready for reading, then the closure is not called + /// If the socket is not ready, then the closure is not called /// and a `WouldBlock` error is returned. /// /// The closure should only return a `WouldBlock` error if it has performed @@ -1165,42 +1165,17 @@ impl UnixDatagram { /// methods defined on the Tokio `UnixDatagram` type, as this will mess with /// the readiness flag and can cause the socket to behave incorrectly. /// - /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// Usually, [`readable()`], [`writable()`] or [`ready()`] is used with this function. /// /// [`readable()`]: UnixDatagram::readable() - /// [`ready()`]: UnixDatagram::ready() - pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::READABLE, f) - } - - /// Try to write from the socket using a user-provided IO operation. - /// - /// If the socket is ready for writing, the provided closure is called. The - /// closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the write readiness flag is cleared. The return value of the closure is - /// then returned by `try_write_io`. - /// - /// If the socket is not ready for writing, then the closure is not called - /// and a `WouldBlock` error is returned. - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `UnixDatagram` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// Usually, [`writable()`] or [`ready()`] is used with this function. - /// /// [`writable()`]: UnixDatagram::writable() /// [`ready()`]: UnixDatagram::ready() - pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::WRITABLE, f) + pub fn try_io( + &self, + interest: Interest, + f: impl FnOnce() -> io::Result, + ) -> io::Result { + self.io.registration().try_io(interest, f) } /// Returns the local address that this socket is bound to. diff --git a/tokio/src/net/unix/stream.rs b/tokio/src/net/unix/stream.rs index c4aa70df6e9..39f6ee258f7 100644 --- a/tokio/src/net/unix/stream.rs +++ b/tokio/src/net/unix/stream.rs @@ -653,16 +653,16 @@ impl UnixStream { .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(buf)) } - /// Try to read from the socket using a user-provided IO operation. + /// Try to perform IO operation from the socket using a user-provided IO operation. /// - /// If the socket is ready for reading, the provided closure is called. The - /// closure should attempt to read from the socket by manually calling the + /// If the socket is ready, the provided closure is called. The + /// closure should attempt to perform IO operation from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The return value of the closure is - /// then returned by `try_read_io`. + /// the readiness flag is cleared. The return value of the closure is + /// then returned by `try_io`. /// - /// If the socket is not ready for reading, then the closure is not called + /// If the socket is not ready, then the closure is not called /// and a `WouldBlock` error is returned. /// /// The closure should only return a `WouldBlock` error if it has performed @@ -675,42 +675,17 @@ impl UnixStream { /// methods defined on the Tokio `UnixStream` type, as this will mess with /// the readiness flag and can cause the socket to behave incorrectly. /// - /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// Usually, [`readable()`], [`writable()`] or [`ready()`] is used with this function. /// /// [`readable()`]: UnixStream::readable() - /// [`ready()`]: UnixStream::ready() - pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::READABLE, f) - } - - /// Try to write from the socket using a user-provided IO operation. - /// - /// If the socket is ready for writing, the provided closure is called. The - /// closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the write readiness flag is cleared. The return value of the closure is - /// then returned by `try_write_io`. - /// - /// If the socket is not ready for writing, then the closure is not called - /// and a `WouldBlock` error is returned. - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `UnixStream` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// Usually, [`writable()`] or [`ready()`] is used with this function. - /// /// [`writable()`]: UnixStream::writable() /// [`ready()`]: UnixStream::ready() - pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::WRITABLE, f) + pub fn try_io( + &self, + interest: Interest, + f: impl FnOnce() -> io::Result, + ) -> io::Result { + self.io.registration().try_io(interest, f) } /// Creates new `UnixStream` from a `std::os::unix::net::UnixStream`. diff --git a/tokio/src/net/windows/named_pipe.rs b/tokio/src/net/windows/named_pipe.rs index 0a97cc3821e..4e7458b58b7 100644 --- a/tokio/src/net/windows/named_pipe.rs +++ b/tokio/src/net/windows/named_pipe.rs @@ -724,64 +724,39 @@ impl NamedPipeServer { .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(buf)) } - /// Try to read from the named pipe using a user-provided IO operation. + /// Try to perform IO operation from the socket using a user-provided IO operation. /// - /// If the named pipe is ready for reading, the provided closure is called. The - /// closure should attempt to read from the named pipe by manually calling the - /// appropriate syscall. If the operation fails because the named pipe is not + /// If the socket is ready, the provided closure is called. The + /// closure should attempt to perform IO operation from the socket by manually calling the + /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The return value of the closure is - /// then returned by `try_read_io`. + /// the readiness flag is cleared. The return value of the closure is + /// then returned by `try_io`. /// - /// If the named pipe is not ready for reading, then the closure is not called + /// If the socket is not ready, then the closure is not called /// and a `WouldBlock` error is returned. /// /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the named pipe that failed due to the named pipe not being + /// an IO operation on the socket that failed due to the socket not being /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the named pipe to + /// incorrectly clear the readiness flag, which can cause the socket to /// behave incorrectly. /// /// The closure should not perform the read operation using any of the /// methods defined on the Tokio `NamedPipeServer` type, as this will mess with - /// the readiness flag and can cause the named pipe to behave incorrectly. + /// the readiness flag and can cause the socket to behave incorrectly. /// - /// Usually, [`readable()`] or [`ready()`] is used with this function. + /// Usually, [`readable()`], [`writable()`] or [`ready()`] is used with this function. /// /// [`readable()`]: NamedPipeServer::readable() - /// [`ready()`]: NamedPipeServer::ready() - pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::READABLE, f) - } - - /// Try to write from the named pipe using a user-provided IO operation. - /// - /// If the named pipe is ready for writing, the provided closure is called. The - /// closure should attempt to write from the named pipe by manually calling the - /// appropriate syscall. If the operation fails because the named pipe is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the write readiness flag is cleared. The return value of the closure is - /// then returned by `try_write_io`. - /// - /// If the named pipe is not ready for writing, then the closure is not called - /// and a `WouldBlock` error is returned. - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the named pipe that failed due to the named pipe not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the named pipe to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `NamedPipeServer` type, as this will mess with - /// the readiness flag and can cause the named pipe to behave incorrectly. - /// - /// Usually, [`writable()`] or [`ready()`] is used with this function. - /// /// [`writable()`]: NamedPipeServer::writable() /// [`ready()`]: NamedPipeServer::ready() - pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::WRITABLE, f) + pub fn try_io( + &self, + interest: Interest, + f: impl FnOnce() -> io::Result, + ) -> io::Result { + self.io.registration().try_io(interest, f) } } @@ -1404,55 +1379,17 @@ impl NamedPipeClient { .try_io(Interest::WRITABLE, || (&*self.io).write_vectored(buf)) } - /// Try to read from the named pipe using a user-provided IO operation. + /// Try to perform IO operation from the socket using a user-provided IO operation. /// - /// If the named pipe is ready for reading, the provided closure is called. The - /// closure should attempt to read from the named pipe by manually calling the - /// appropriate syscall. If the operation fails because the named pipe is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The return value of the closure is - /// then returned by `try_read_io`. - /// - /// If the named pipe is not ready for reading, then the closure is not called - /// and a `WouldBlock` error is returned. - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the named pipe that failed due to the named pipe not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the named pipe to - /// behave incorrectly. - /// - /// The closure should not perform the read operation using any of the - /// methods defined on the Tokio `NamedPipeClient` type, as this will mess with - /// the readiness flag and can cause the named pipe to behave incorrectly. - /// - /// Usually, [`readable()`] or [`ready()`] is used with this function. - /// - /// [`readable()`]: NamedPipeClient::readable() - /// [`ready()`]: NamedPipeClient::ready() - pub fn try_read_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::READABLE, f) - } - - /// Poll for read readiness, then reads from the socket using a user-provided IO operation. - /// - /// If the named pipe is not currently ready for reading, this method will - /// store a clone of the `Waker` from the provided `Context`. When the named - /// pipe becomes ready for reading, `Waker::wake` will be called on the - /// waker. - /// - /// If the named pipe is ready for reading, the provided closure is called. - /// The closure should attempt to read from the socket by manually calling the + /// If the socket is ready, the provided closure is called. The + /// closure should attempt to perform IO operation from the socket by manually calling the /// appropriate syscall. If the operation fails because the socket is not /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` - /// will be called on the waker. + /// the readiness flag is cleared. The return value of the closure is + /// then returned by `try_io`. /// - /// Note that on multiple calls to `poll_read_io`, `poll_read`, - /// `poll_read_ready` or `poll_peek`, only the `Waker` from the `Context` - /// passed to the most recent call is scheduled to receive a wakeup. - /// (However, `poll_write_io` retains a second, independent waker.) + /// If the socket is not ready, then the closure is not called + /// and a `WouldBlock` error is returned. /// /// The closure should only return a `WouldBlock` error if it has performed /// an IO operation on the socket that failed due to the socket not being @@ -1464,102 +1401,17 @@ impl NamedPipeClient { /// methods defined on the Tokio `NamedPipeClient` type, as this will mess with /// the readiness flag and can cause the socket to behave incorrectly. /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the named pipe is not ready for reading, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_read_io( - &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_read_io(cx, f) - } - - /// Try to write from the named pipe using a user-provided IO operation. - /// - /// If the named pipe is ready for writing, the provided closure is called. The - /// closure should attempt to write from the named pipe by manually calling the - /// appropriate syscall. If the operation fails because the named pipe is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the write readiness flag is cleared. The return value of the closure is - /// then returned by `try_write_io`. - /// - /// If the named pipe is not ready for writing, then the closure is not called - /// and a `WouldBlock` error is returned. - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the named pipe that failed due to the named pipe not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the named pipe to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `NamedPipeClient` type, as this will mess with - /// the readiness flag and can cause the named pipe to behave incorrectly. - /// - /// Usually, [`writable()`] or [`ready()`] is used with this function. + /// Usually, [`readable()`], [`writable()`] or [`ready()`] is used with this function. /// + /// [`readable()`]: NamedPipeClient::readable() /// [`writable()`]: NamedPipeClient::writable() /// [`ready()`]: NamedPipeClient::ready() - pub fn try_write_io(&self, f: impl FnOnce() -> io::Result) -> io::Result { - self.io.registration().try_io(Interest::WRITABLE, f) - } - - /// Poll for write readiness, then writes to the socket using a user-provided IO operation. - /// - /// If the named pipe is not currently ready for writing, this method will - /// store a clone of the `Waker` from the provided `Context`. When the named - /// pipe becomes ready for writing, `Waker::wake` will be called on the - /// waker. - /// - /// If the named pipe is ready for writing, the provided closure is called. - /// The closure should attempt to write from the socket by manually calling the - /// appropriate syscall. If the operation fails because the socket is not - /// actually ready, then the closure should return a `WouldBlock` error and - /// the read readiness flag is cleared. The `Waker` from the provided `Context` - /// will be stored. When the named pipe becomes ready for reading, `Waker::wake` - /// will be called on the waker. - /// - /// Note that on multiple calls to `poll_write_io` only - /// the `Waker` from the `Context` passed to the most recent call is - /// scheduled to receive a wakeup. (However, `poll_read_io` retains a - /// second, independent waker.) - /// - /// The closure should only return a `WouldBlock` error if it has performed - /// an IO operation on the socket that failed due to the socket not being - /// ready. Returning a `WouldBlock` error in any other situation will - /// incorrectly clear the readiness flag, which can cause the socket to - /// behave incorrectly. - /// - /// The closure should not perform the write operation using any of the - /// methods defined on the Tokio `NamedPipeClient` type, as this will mess with - /// the readiness flag and can cause the socket to behave incorrectly. - /// - /// # Return value - /// - /// The function returns: - /// - /// * `Poll::Pending` if the named pipe is not ready for writing, or if `f` returns a `WouldBlock` error. - /// * `Poll::Ready(Ok(r))` if `f` returns `Ok(r)`. - /// * `Poll::Ready(Err(e))` if `f` returns an error other than `WouldBlock`, or if polling for readiness encounters an IO error. - /// - /// # Errors - /// - /// This function may encounter any standard I/O error except `WouldBlock`. - pub fn poll_write_io( + pub fn try_io( &self, - cx: &mut Context<'_>, - f: impl FnMut() -> io::Result, - ) -> Poll> { - self.io.registration().poll_write_io(cx, f) + interest: Interest, + f: impl FnOnce() -> io::Result, + ) -> io::Result { + self.io.registration().try_io(interest, f) } }