diff --git a/tokio/src/io/poll_evented.rs b/tokio/src/io/poll_evented.rs index 3a6596108a1..7a42ad7dd44 100644 --- a/tokio/src/io/poll_evented.rs +++ b/tokio/src/io/poll_evented.rs @@ -124,6 +124,16 @@ impl PollEvented { pub(crate) fn registration(&self) -> &Registration { &self.registration } + + /// Deregister the inner io from the registration and returns a Result containing the inner io + pub(crate) fn into_inner(mut self) -> io::Result { + let mut inner = self + .io + .take() + .ok_or(io::Error::from(io::ErrorKind::NotFound))?; + self.registration.deregister(&mut inner)?; + Ok(inner) + } } feature! { diff --git a/tokio/src/net/tcp/stream.rs b/tokio/src/net/tcp/stream.rs index 28118f73f2a..4ab798f9b07 100644 --- a/tokio/src/net/tcp/stream.rs +++ b/tokio/src/net/tcp/stream.rs @@ -9,10 +9,10 @@ use std::fmt; use std::io; use std::net::{Shutdown, SocketAddr}; #[cfg(windows)] -use std::os::windows::io::{AsRawSocket, FromRawSocket}; +use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket}; #[cfg(unix)] -use std::os::unix::io::{AsRawFd, FromRawFd}; +use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd}; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::Duration; @@ -184,6 +184,25 @@ impl TcpStream { Ok(TcpStream { io }) } + /// Turn a `TcpStream` into a `std::net::TcpStream`. + pub fn into_std(self) -> io::Result { + #[cfg(unix)] + { + self.io + .into_inner() + .map(|io| io.into_raw_fd()) + .map(|raw_fd| unsafe { std::net::TcpStream::from_raw_fd(raw_fd) }) + } + + #[cfg(windows)] + { + self.io + .into_inner() + .map(|io| io.into_raw_socket()) + .map(|raw_socket| unsafe { std::net::TcpStream::from_raw_socket(raw_socket) }) + } + } + /// Returns the local address that this stream is bound to. /// /// # Examples