Skip to content
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

Update Mio to 0.7 #1767

Closed
wants to merge 23 commits into from

Conversation

kleimkuhler
Copy link
Contributor

@kleimkuhler kleimkuhler commented Nov 12, 2019

Summary

This PR updates Tokio to Mio master. A version 0.7 has not been released
yet, but that is the intention of this change.

There should be no user-facing changes from this update. All changes are
confined to tokio::net with the majority taking place in
net::driver::reactor and net::util::PollEvented (now
net::util::IoResource). Therefore, no tests have been added or changed.

Details

PollEvented -> IoResource

With the change of mio::Evented -> mio::event::Source, it made sense to
change the Tokio wrapper as well. As this type is responsible for driving
all I/O resources, the name seemed to fit.

The internal API for IoResource have changed so that an interest/readiness
does not need to be passed in to the poll functions (poll_read_ready and
poll_write_ready). Both poll functions expand via poll_readiness! which is
responsible for driving the actual readiness of events on the I/O resource.

Readiness represents any cross-platform event that has occurred on the I/O
resource since the last poll. The possible values are: READABLE,
WRITEABLE, READ_CLOSED, and WRITE_CLOSED.

poll_readiness! will poll the I/O resource until there is a readiness event
that matches an event of interest. If there already is an event of interest
then it will return.

Finally, poll_readiness! does not actually implement the low-level polling
on the I/O resource. It dispatches to a Registration which changed mainly to
handle closed events.

Temporarily removed methods

The following TcpStream methods were removed due to changes in the Mio API.
They will be reintroduced in further changes that either implement these
directly in Tokio, or Mio introducing a TcpSocket builder type that can be
used by Tokio.

TcpStream::

  • connect_std
  • recv_buff_size
  • set_recv_buffer_size
  • send_buffer_size
  • set_send_buffer_size
  • keepalive
  • set_keepalive
  • linger
  • set_linger

{AsyncRead, AsyncWrite}::poll_read_buf

This method relies on the Bytes update so that IoSlice can be used. This
temporarily performs un-vectored reads and writes.

Signed-off-by: Kevin Leimkuhler [email protected]

@kleimkuhler kleimkuhler marked this pull request as ready for review November 13, 2019 05:23
@kleimkuhler
Copy link
Contributor Author

This currently fails on Windows because of the use of mio-named-pipes which still depends on Mio 0.6. Will work on a fix for this, but those changes should be confined to tokio::process::windows

@@ -1,28 +0,0 @@
pub(crate) use self::sys::*;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleting this file makes me happy.

@@ -266,7 +275,7 @@ impl Reactor {
#[cfg(all(unix, not(target_os = "fuchsia")))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can delete any mention of fuchsia as there is no fuchsia support ATM.

// This consumes the current readiness state **except** for
// `READ_CLOSED` and `WRITE_CLOSED`. These are excluded because:
// - They are a final state and never transitioned out of
// - Both the read and the write directions should be able to observe
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line isn't really relevant anymore.

/// [`poll_read_ready`]: #method.poll_read_ready
/// [`poll_write_ready`]: #method.poll_write_ready
pub struct IoResource<S: mio::event::Source> {
io: Option<S>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are in here, can Option be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can! I was going to do it as part of this PR, but since IoResource::into_inner moves the value out, the Drop impl requires some additional handling to forget the value when this occurs. I can include it now, but had it as a note for a follow-up. It should be a fairly small change.

Copy link
Contributor

@Thomasdezeeuw Thomasdezeeuw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a quick look and left some comments.

Overall I don't see many change that relate to using edge-triggers. Was Mio already using edge-trigger before? Last time I look was with futures 0.1, so its been a while and lots has changed.

@@ -93,14 +91,13 @@ iovec = "0.1"
fnv = { version = "1.0.6", optional = true }
lazy_static = { version = "1.0.2", optional = true }
memchr = { version = "2.2", optional = true }
mio = { version = "0.6.14", optional = true }
mio = { git = "https://github.com/tokio-rs/mio", branch = "master", optional = true }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to fix to a specific commit to avoid breaking changes.

Ok(_) => {}
Err(e) => return Err(e),
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably add a loop here, now you're continueing with no events.

@@ -321,7 +330,7 @@ impl Handle {
/// return immediately.
fn wakeup(&self) {
if let Some(inner) = self.inner() {
inner.wakeup.set_readiness(mio::Ready::readable()).unwrap();
inner.waker.wake().expect("failed to wake reactor")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you want to return the error here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wakeup is only used in Handle::unpark which does not return anything. I think handling an error here could be considered, but not necessarily as part of this change. Similar to before, if there an unexpected reason why wakeup fails then a panic will happen.

};

waker.register(w);
if readiness & ready.as_usize() != 0 {
if readiness & interest.as_usize() != 0 {
waker.wake();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call is now quite a bit more expansive then in Mio v0.6, since in v0.7 this is a system call. You might want to consider using a different mechanism for this.

const READABLE: usize = 0b0_01;
const WRITABLE: usize = 0b0_10;
const READ_CLOSED: usize = 0b0_0100;
const WRITE_CLOSED: usize = 0b0_1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing AIO (not supported), LIO (not supported), error and priority. This is the full list (from tokio-rs/mio#1145):

const READABLE: usize = 0b00_000_001;
const WRITABLE: usize = 0b00_000_010;
const AIO: usize = 0b00_000_100;
const LIO: usize = 0b00_001_000;
const ERROR: usize = 0b00_010_000;
const READ_CLOSED: usize = 0b00_100_000;
const WRITE_CLOSED: usize = 0b01_000_000;
const PRIORITY: usize = 0b10_000_000;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also just fits in 8 bits, if size is something to optimise for here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep I left those out for now. Readable and writeable readiness were supported before, and now Mio offers the cross-platform closed readiness that allows this change to remove platform-specific behavior. If support for these platform specific events provides values I think it should be done in a PR that is focused on adding functionality and not just updating.

/// [`TcpListener`] implements poll_accept by using [`poll_read_ready`] and
/// [`clear_read_ready`].
///
/// TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple TODOs left in these docs.

Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
Signed-off-by: Kevin Leimkuhler <[email protected]>
@kleimkuhler
Copy link
Contributor Author

Closing as I'd like to keep this branch up to date as both libraries change towards their next big releases, and I will be making some temporary changes so that it stays compiling/testing on at least some platforms.

@carllerche carllerche mentioned this pull request Sep 28, 2020
2 tasks
carllerche added a commit that referenced this pull request Oct 2, 2020
This also makes Mio an implementation detail, removing it from the
public API.

This is based on #1767.
@monkeygroover
Copy link

Hi QQ, set_keepalive is noted as being temporarily removed, has this subsequently moved elsewhere or is there an alternative way to set the socket option?

cheers

Rich

@Darksonn
Copy link
Contributor

Darksonn commented Jan 6, 2021

See more at #3082.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants