-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
net: add a into_std method for tokio's TcpStream #3189
Conversation
2c5c087
to
86382a4
Compare
6b2147e
to
cf99d4e
Compare
cf99d4e
to
6763153
Compare
Fixes: tokio-rs#3031 Signed-off-by: Fuyang Liu <liufuyang@users.noreply.github.com>
6763153
to
34ac3e5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems ok to me.
@Thomasdezeeuw is there a better way to convert the mio TcpStream
than going through RawFd
or RawSocket
? I don't see one myself.
@Darksonn not right now, but there is tokio-rs/mio#1401. |
tokio/src/io/poll_evented.rs
Outdated
let mut inner = self | ||
.io | ||
.take() | ||
.ok_or_else(|| io::Error::from(io::ErrorKind::NotFound))?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that other parts of the code just unwrap
this. Is it the case that it is an Option
only for the purpose of being possible to take it out in or before the destructor? @carllerche
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, a panic here is fine as it would be an internal bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe @Darksonn is correct — this shouldn't ever be None
unless the PollEvented
is being dropped or into_std
has been called, so this can just be an unwrap()
...
Signed-off-by: Fuyang Liu <liufuyang@users.noreply.github.com>
Signed-off-by: Fuyang Liu <liufuyang@users.noreply.github.com>
Hey @Darksonn, thanks for the comments above. I also added a doc test so to make a std TcpStream and let a client read it. Do you think the test code is solid enough? Or should I add a normal unit test for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some stylistic comments on the doc-test.
tokio/src/net/tcp/stream.rs
Outdated
/// # let mut stream: TcpStream = TcpStream::connect("127.0.0.1:8080").await.unwrap(); | ||
/// # let _ = stream.write(b"Hello world!").await; | ||
/// # }); | ||
/// let mut data = [0 as u8; 50]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// let mut data = [0 as u8; 50]; | |
/// let mut data = [0u8; 50]; |
tokio/src/net/tcp/stream.rs
Outdated
/// #[tokio::main] | ||
/// async fn main() -> Result<(), Box<dyn Error>> { | ||
/// # tokio::spawn(async { | ||
/// # tokio::time::sleep(Duration::from_millis(50)).await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can avoid this sleep if you spawn it after calling bind
. Also, can you await the returned JoinHandle
at the end of the test to make sure the test fails if the task panics?
tokio/src/net/tcp/stream.rs
Outdated
/// let (tokio_tcp_stream, _) = listener.accept().await?; | ||
/// | ||
/// let mut std_tcp_stream = tokio_tcp_stream.into_std()?; | ||
/// # tokio::time::sleep(Duration::from_millis(100)).await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sleep should be unnecessary.
tokio/src/net/tcp/stream.rs
Outdated
/// # tokio::spawn(async { | ||
/// # tokio::time::sleep(Duration::from_millis(50)).await; | ||
/// # let mut stream: TcpStream = TcpStream::connect("127.0.0.1:8080").await.unwrap(); | ||
/// # let _ = stream.write(b"Hello world!").await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// # let _ = stream.write(b"Hello world!").await; | |
/// # stream.write(b"Hello world!").await.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems I need this otherwise I see this during test?
running 1 test
test src/net/tcp/stream.rs - net::tcp::stream::TcpStream::into_std (line 191) ... FAILED
failures:
---- src/net/tcp/stream.rs - net::tcp::stream::TcpStream::into_std (line 191) stdout ----
error: unused `std::result::Result` that must be used
--> src/net/tcp/stream.rs:204:7
|
15 | stream.write(b"Hello world!").await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> src/net/tcp/stream.rs:190:9
|
1 | #![deny(warnings, rust_2018_idioms)]
| ^^^^^^^^
= note: `#[deny(unused_must_use)]` implied by `#[deny(warnings)]`
= note: this `Result` may be an `Err` variant, which should be handled
error: aborting due to previous error
Couldn't compile the test.
failures:
src/net/tcp/stream.rs - net::tcp::stream::TcpStream::into_std (line 191)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need the unwrap()
too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, thanks 😄
tokio/src/net/tcp/stream.rs
Outdated
/// let mut std_tcp_stream = tokio_tcp_stream.into_std()?; | ||
/// # tokio::time::sleep(Duration::from_millis(100)).await; | ||
/// let size = std_tcp_stream.read(&mut data)?; | ||
/// # assert_eq!("Hello world!", std::str::from_utf8(&data[0..size])?); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// # assert_eq!("Hello world!", std::str::from_utf8(&data[0..size])?); | |
/// # assert_eq!(b"Hello world!", &data[0..size]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, nice :)
tokio/src/net/tcp/stream.rs
Outdated
/// # tokio::time::sleep(Duration::from_millis(100)).await; | ||
/// let size = std_tcp_stream.read(&mut data)?; | ||
/// # assert_eq!("Hello world!", std::str::from_utf8(&data[0..size])?); | ||
/// # Ok(()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this, it wont compile if the user pastes it into the playground.
/// # Ok(()) | |
/// Ok(()) |
I think it would be worth adding a test that the Besides that, I think the doc-test captures what I'm looking for. |
Signed-off-by: Fuyang Liu <liufuyang@users.noreply.github.com>
Signed-off-by: Fuyang Liu <liufuyang@users.noreply.github.com>
Signed-off-by: Fuyang Liu <liufuyang@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good, besides a missing space.
tokio/src/net/tcp/stream.rs
Outdated
/// std_tcp_stream.set_nonblocking(false)?; | ||
/// std_tcp_stream.read_exact(&mut data)?; | ||
/// # assert_eq!(b"Hello world!", &data); | ||
/// Ok(()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Ok(()) | |
/// Ok(()) |
Motivation
Closes #3031
Solution
into_inner
method onPollEvented
. Make sure to deregister the stream from Tokio.mio
tcp stream into an std one. Go through mio'sIntoRawFd
to do so.