aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2021-04-12 18:01:52 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-04-12 18:01:52 +0000
commitfe2e884eb79836e363bc94b63cb778f401d89185 (patch)
tree9d90156cdc95cd4ef05a842b91127753b251d0a0
parent06a15afe7a0ed4b44ff4f21fb52f3bce5dfa13c8 (diff)
parent5e4d5d3742c7e8d82e4e5f7cf0d08e7121b5baf8 (diff)
downloadmio-fe2e884eb79836e363bc94b63cb778f401d89185.tar.gz
Upgrade rust/crates/mio to 0.7.11 am: aa25fe6ab1 am: ef95edc9d2 am: 6211263feb am: 5e4d5d3742
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/mio/+/1662926 Change-Id: I16e0b0630b203ecae143d4dca354105d7a821ebc
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp3
-rw-r--r--CHANGELOG.md24
-rw-r--r--Cargo.lock27
-rw-r--r--Cargo.toml4
-rw-r--r--Cargo.toml.orig4
-rw-r--r--METADATA8
-rw-r--r--TEST_MAPPING14
-rw-r--r--src/lib.rs2
-rw-r--r--src/macros.rs2
-rw-r--r--src/sys/unix/tcp.rs27
-rw-r--r--src/sys/unix/uds/listener.rs22
-rw-r--r--src/sys/windows/afd.rs6
-rw-r--r--src/sys/windows/named_pipe.rs131
14 files changed, 201 insertions, 75 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index f8fb5d1..d513c37 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "20b7298fe0d3da04b965ec4a379db0247cd632be"
+ "sha1": "772c692150c711d7bdd72b5c6287072b8914e519"
}
}
diff --git a/Android.bp b/Android.bp
index 9fec9f1..8812f69 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,5 @@
// This file is generated by cargo2android.py --run --device --dependencies --features os-poll,tcp,udp,uds,os-util --patch=patches/Android.bp.patch.
+// Do not modify this file as changes will be overridden on upgrade.
package {
default_applicable_licenses: ["external_rust_crates_mio_license"],
@@ -45,5 +46,5 @@ rust_library {
// dependent_library ["feature_list"]
// cfg-if-1.0.0
-// libc-0.2.86 "align,default,std"
+// libc-0.2.92 "default,std"
// log-0.4.14 "std"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2f23320..72cb770 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,27 @@
+# 0.7.11
+
+## Fixes
+
+* Fix missing feature of winapi.
+ (https://github.com/tokio-rs/mio/commit/a7e61db9e3c2b929ef1a33532bfcc22045d163ce).
+
+# 0.7.10
+
+## Fixes
+
+* Fix an instance of not doc(cfg(.*))
+ (https://github.com/tokio-rs/mio/commit/25e8f911357c740034f10a170dfa4ea1b28234ce).
+
+## Fixes
+
+* Fix error handling in `NamedPipe::write`
+ (https://github.com/tokio-rs/mio/commit/aec872be9732e5c6685100674278be27f54a271b).
+* Use `accept(2)` on x86 Android instead of `accept4(2)`
+ (https://github.com/tokio-rs/mio/commit/6f86b925d3e48f30905d5cfa54348acf3f1fa036,
+ https://github.com/tokio-rs/mio/commit/8d5414880ab82178305ac1d2c16d715e58633d3e).
+* Improve error message when opening AFD device
+ (https://github.com/tokio-rs/mio/commit/139f7c4422321eb4a17b14ae2c296fddd19a8804).
+
# 0.7.8
## Fixes
diff --git a/Cargo.lock b/Cargo.lock
index 0e25467..c91bfb8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,10 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-[[package]]
-name = "cfg-if"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+version = 3
[[package]]
name = "cfg-if"
@@ -35,16 +31,16 @@ checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
[[package]]
name = "log"
-version = "0.4.11"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if",
]
[[package]]
name = "mio"
-version = "0.7.8"
+version = "0.7.11"
dependencies = [
"env_logger",
"libc",
@@ -112,20 +108,13 @@ dependencies = [
]
[[package]]
-name = "redox_syscall"
-version = "0.1.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
-
-[[package]]
name = "socket2"
-version = "0.3.17"
+version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902"
+checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"libc",
- "redox_syscall",
"winapi",
]
diff --git a/Cargo.toml b/Cargo.toml
index 80f9f6e..62090ff 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "mio"
-version = "0.7.8"
+version = "0.7.11"
authors = ["Carl Lerche <me@carllerche.com>", "Thomas de Zeeuw <thomasdezeeuw@gmail.com>", "Tokio Contributors <team@tokio.rs>"]
include = ["Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", "src/**/*.rs", "examples/**/*.rs"]
description = "Lightweight non-blocking IO"
@@ -69,4 +69,4 @@ version = "0.3"
[target."cfg(windows)".dependencies.winapi]
version = "0.3"
-features = ["winsock2", "mswsock"]
+features = ["winsock2", "mswsock", "mstcpip"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 0d4b1d8..a14d17d 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -6,7 +6,7 @@ name = "mio"
# - Update CHANGELOG.md.
# - Update doc URL.
# - Create git tag
-version = "0.7.8"
+version = "0.7.11"
license = "MIT"
authors = [
"Carl Lerche <me@carllerche.com>",
@@ -57,7 +57,7 @@ libc = "0.2.86"
[target.'cfg(windows)'.dependencies]
miow = "0.3.6"
-winapi = { version = "0.3", features = ["winsock2", "mswsock"] }
+winapi = { version = "0.3", features = ["winsock2", "mswsock", "mstcpip"] }
ntapi = "0.3"
[dev-dependencies]
diff --git a/METADATA b/METADATA
index 9864d68..eb89225 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/mio/mio-0.7.8.crate"
+ value: "https://static.crates.io/crates/mio/mio-0.7.11.crate"
}
- version: "0.7.8"
+ version: "0.7.11"
license_type: NOTICE
last_upgrade_date {
year: 2021
- month: 2
- day: 17
+ month: 4
+ day: 1
}
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index c1780b5..fadb544 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -2,10 +2,22 @@
{
"presubmit": [
{
- "name": "quiche_device_test_src_lib"
+ "name": "tokio-test_device_test_tests_macros"
+ },
+ {
+ "name": "tokio-test_device_test_tests_block_on"
+ },
+ {
+ "name": "tokio-test_device_test_tests_io"
},
{
"name": "futures-util_device_test_src_lib"
+ },
+ {
+ "name": "tokio-test_device_test_src_lib"
+ },
+ {
+ "name": "quiche_device_test_src_lib"
}
]
}
diff --git a/src/lib.rs b/src/lib.rs
index fedb789..ad417c2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,4 @@
-#![doc(html_root_url = "https://docs.rs/mio/0.7.8")]
+#![doc(html_root_url = "https://docs.rs/mio/0.7.11")]
#![deny(
missing_docs,
missing_debug_implementations,
diff --git a/src/macros.rs b/src/macros.rs
index db93dfd..f97f909 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -52,7 +52,7 @@ macro_rules! cfg_io_source {
($($item:item)*) => {
$(
#[cfg(any(feature = "net", all(unix, feature = "os-ext")))]
- #[cfg_attr(docsrs, doc(any(feature = "net", all(unix, feature = "os-ext"))))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "net", all(unix, feature = "os-ext")))))]
$item
)*
}
diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs
index 70986fa..59642c6 100644
--- a/src/sys/unix/tcp.rs
+++ b/src/sys/unix/tcp.rs
@@ -429,7 +429,12 @@ pub fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, Socket
// On platforms that support it we can use `accept4(2)` to set `NONBLOCK`
// and `CLOEXEC` in the call to accept the connection.
#[cfg(any(
- target_os = "android",
+ // Android x86's seccomp profile forbids calls to `accept4(2)`
+ // See https://github.com/tokio-rs/mio/issues/1445 for details
+ all(
+ not(target_arch="x86"),
+ target_os = "android"
+ ),
target_os = "dragonfly",
target_os = "freebsd",
target_os = "illumos",
@@ -450,7 +455,15 @@ pub fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, Socket
// But not all platforms have the `accept4(2)` call. Luckily BSD (derived)
// OSes inherit the non-blocking flag from the listener, so we just have to
// set `CLOEXEC`.
- #[cfg(any(target_os = "ios", target_os = "macos", target_os = "solaris"))]
+ #[cfg(any(
+ all(
+ target_arch = "x86",
+ target_os = "android"
+ ),
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "solaris"
+ ))]
let stream = {
syscall!(accept(
listener.as_raw_fd(),
@@ -458,7 +471,15 @@ pub fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, Socket
&mut length
))
.map(|socket| unsafe { net::TcpStream::from_raw_fd(socket) })
- .and_then(|s| syscall!(fcntl(s.as_raw_fd(), libc::F_SETFD, libc::FD_CLOEXEC)).map(|_| s))
+ .and_then(|s| {
+ syscall!(fcntl(s.as_raw_fd(), libc::F_SETFD, libc::FD_CLOEXEC))?;
+
+ // See https://github.com/tokio-rs/mio/issues/1450
+ #[cfg(all(target_arch = "x86",target_os = "android"))]
+ syscall!(fcntl(s.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK))?;
+
+ Ok(s)
+ })
}?;
// This is safe because `accept` calls above ensures the address
diff --git a/src/sys/unix/uds/listener.rs b/src/sys/unix/uds/listener.rs
index b8fb5a9..547ff57 100644
--- a/src/sys/unix/uds/listener.rs
+++ b/src/sys/unix/uds/listener.rs
@@ -42,7 +42,13 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
- target_os = "solaris"
+ target_os = "solaris",
+ // Android x86's seccomp profile forbids calls to `accept4(2)`
+ // See https://github.com/tokio-rs/mio/issues/1445 for details
+ all(
+ target_arch = "x86",
+ target_os = "android"
+ )
)))]
let socket = {
let flags = libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
@@ -59,7 +65,11 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
- target_os = "solaris"
+ target_os = "solaris",
+ all(
+ target_arch = "x86",
+ target_os = "android"
+ )
))]
let socket = syscall!(accept(
listener.as_raw_fd(),
@@ -70,7 +80,13 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So
// Ensure the socket is closed if either of the `fcntl` calls
// error below.
let s = unsafe { net::UnixStream::from_raw_fd(socket) };
- syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC)).map(|_| s)
+ syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC))?;
+
+ // See https://github.com/tokio-rs/mio/issues/1450
+ #[cfg(all(target_arch = "x86",target_os = "android"))]
+ syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK))?;
+
+ Ok(s)
});
socket
diff --git a/src/sys/windows/afd.rs b/src/sys/windows/afd.rs
index bf3704d..6241a45 100644
--- a/src/sys/windows/afd.rs
+++ b/src/sys/windows/afd.rs
@@ -188,9 +188,11 @@ cfg_io_source! {
0 as ULONG,
);
if status != STATUS_SUCCESS {
- return Err(io::Error::from_raw_os_error(
+ let raw_err = io::Error::from_raw_os_error(
RtlNtStatusToDosError(status) as i32
- ));
+ );
+ let msg = format!("Failed to open \\Device\\Afd\\Mio: {}", raw_err);
+ return Err(io::Error::new(raw_err.kind(), msg));
}
let fd = File::from_raw_handle(afd_helper_handle as RawHandle);
// Increment by 2 to reserve space for other types of handles.
diff --git a/src/sys/windows/named_pipe.rs b/src/sys/windows/named_pipe.rs
index a5688ce..8c81f38 100644
--- a/src/sys/windows/named_pipe.rs
+++ b/src/sys/windows/named_pipe.rs
@@ -1,6 +1,6 @@
-use crate::{poll, Registry};
use crate::event::Source;
use crate::sys::windows::{Event, Overlapped};
+use crate::{poll, Registry};
use winapi::um::minwinbase::OVERLAPPED_ENTRY;
use std::ffi::OsStr;
@@ -9,8 +9,8 @@ use std::io::{self, Read, Write};
use std::mem;
use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
use std::slice;
-use std::sync::atomic::{AtomicUsize, AtomicBool};
use std::sync::atomic::Ordering::{Relaxed, SeqCst};
+use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::{Arc, Mutex};
use crate::{Interest, Token};
@@ -128,9 +128,7 @@ fn would_block() -> io::Error {
impl NamedPipe {
/// Creates a new named pipe at the specified `addr` given a "reasonable
/// set" of initial configuration options.
- pub fn new<A: AsRef<OsStr>>(
- addr: A,
- ) -> io::Result<NamedPipe> {
+ pub fn new<A: AsRef<OsStr>>(addr: A) -> io::Result<NamedPipe> {
let pipe = pipe::NamedPipe::new(addr)?;
// Safety: nothing actually unsafe about this. The trait fn includes
// `unsafe`.
@@ -226,9 +224,7 @@ impl NamedPipe {
}
impl FromRawHandle for NamedPipe {
- unsafe fn from_raw_handle(
- handle: RawHandle,
- ) -> NamedPipe {
+ unsafe fn from_raw_handle(handle: RawHandle) -> NamedPipe {
NamedPipe {
inner: Arc::new(Inner {
// Safety: not really unsafe
@@ -281,9 +277,7 @@ impl<'a> Read for &'a NamedPipe {
match mem::replace(&mut state.read, State::None) {
// In theory not possible with `token` checked above,
// but return would block for now.
- State::None => {
- Err(would_block())
- }
+ State::None => Err(would_block()),
// A read is in flight, still waiting for it to finish
State::Pending(buf, amt) => {
@@ -324,7 +318,7 @@ impl<'a> Read for &'a NamedPipe {
}
impl<'a> Write for &'a NamedPipe {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
// Make sure there's no writes pending
let mut io = self.inner.io.lock().unwrap();
@@ -334,6 +328,12 @@ impl<'a> Write for &'a NamedPipe {
match io.write {
State::None => {}
+ State::Err(_) => match mem::replace(&mut io.write, State::None) {
+ State::Err(e) => return Err(e),
+ // `io` is locked, so this branch is unreachable
+ _ => unreachable!(),
+ },
+ // any other state should be handled in `write_done`
_ => {
return Err(would_block());
}
@@ -342,17 +342,26 @@ impl<'a> Write for &'a NamedPipe {
// Move `buf` onto the heap and fire off the write
let mut owned_buf = self.inner.get_buffer();
owned_buf.extend(buf);
- Inner::schedule_write(&self.inner, owned_buf, 0, &mut io, None);
- Ok(buf.len())
+ match Inner::maybe_schedule_write(&self.inner, owned_buf, 0, &mut io)? {
+ // Some bytes are written immediately
+ Some(n) => Ok(n),
+ // Write operation is anqueued for whole buffer
+ None => Ok(buf.len()),
+ }
}
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
+ fn flush(&mut self) -> io::Result<()> {
+ Ok(())
}
}
impl Source for NamedPipe {
- fn register(&mut self, registry: &Registry, token: Token, interest: Interest) -> io::Result<()> {
+ fn register(
+ &mut self,
+ registry: &Registry,
+ token: Token,
+ interest: Interest,
+ ) -> io::Result<()> {
let mut io = self.inner.io.lock().unwrap();
io.check_association(registry, false)?;
@@ -368,7 +377,10 @@ impl Source for NamedPipe {
io.cp = Some(poll::selector(registry).clone_port());
let inner_token = NEXT_TOKEN.fetch_add(2, Relaxed) + 2;
- poll::selector(registry).inner.cp.add_handle(inner_token, &self.inner.handle)?;
+ poll::selector(registry)
+ .inner
+ .cp
+ .add_handle(inner_token, &self.inner.handle)?;
}
io.token = Some(token);
@@ -381,7 +393,12 @@ impl Source for NamedPipe {
Ok(())
}
- fn reregister(&mut self, registry: &Registry, token: Token, interest: Interest) -> io::Result<()> {
+ fn reregister(
+ &mut self,
+ registry: &Registry,
+ token: Token,
+ interest: Interest,
+ ) -> io::Result<()> {
let mut io = self.inner.io.lock().unwrap();
io.check_association(registry, true)?;
@@ -491,19 +508,61 @@ impl Inner {
}
}
- fn schedule_write(me: &Arc<Inner>, buf: Vec<u8>, pos: usize, io: &mut Io, events: Option<&mut Vec<Event>>) {
+ /// Maybe schedules overlapped write operation.
+ ///
+ /// * `None` means that overlapped operation was enqueued
+ /// * `Some(n)` means that `n` bytes was immediately written.
+ /// Note, that `write_done` will fire anyway to clean up the state.
+ fn maybe_schedule_write(
+ me: &Arc<Inner>,
+ buf: Vec<u8>,
+ pos: usize,
+ io: &mut Io,
+ ) -> io::Result<Option<usize>> {
// Very similar to `schedule_read` above, just done for the write half.
let e = unsafe {
let overlapped = me.write.as_ptr() as *mut _;
me.handle.write_overlapped(&buf[pos..], overlapped)
};
+ // See `connect` above for the rationale behind `forget`
match e {
- // See `connect` above for the rationale behind `forget`
- Ok(_) => {
+ // `n` bytes are written immediately
+ Ok(Some(n)) => {
+ io.write = State::Ok(buf, pos);
+ mem::forget(me.clone());
+ Ok(Some(n))
+ }
+ // write operation is enqueued
+ Ok(None) => {
io.write = State::Pending(buf, pos);
- mem::forget(me.clone())
+ mem::forget(me.clone());
+ Ok(None)
}
+ Err(e) => Err(e),
+ }
+ }
+
+ fn schedule_write(
+ me: &Arc<Inner>,
+ buf: Vec<u8>,
+ pos: usize,
+ io: &mut Io,
+ events: Option<&mut Vec<Event>>,
+ ) {
+ match Inner::maybe_schedule_write(me, buf, pos, io) {
+ Ok(Some(_)) => {
+ // immediate result will be handled in `write_done`,
+ // so we'll reinterpret the `Ok` state
+ let state = mem::replace(&mut io.write, State::None);
+ io.write = match state {
+ State::Ok(buf, pos) => State::Pending(buf, pos),
+ // io is locked, so this branch is unreachable
+ _ => unreachable!(),
+ };
+ mem::forget(me.clone());
+ }
+ Ok(None) => (),
Err(e) => {
io.write = State::Err(e);
io.notify_writable(events);
@@ -610,6 +669,12 @@ fn write_done(status: &OVERLAPPED_ENTRY, events: Option<&mut Vec<Event>>) {
// then we're writable again and otherwise we schedule another write.
let mut io = me.io.lock().unwrap();
let (buf, pos) = match mem::replace(&mut io.write, State::None) {
+ // `Ok` here means, that the operation was completed immediately
+ // `bytes_transferred` is already reported to a client
+ State::Ok(..) => {
+ io.notify_writable(events);
+ return;
+ }
State::Pending(buf, pos) => (buf, pos),
_ => unreachable!(),
};
@@ -638,18 +703,14 @@ fn write_done(status: &OVERLAPPED_ENTRY, events: Option<&mut Vec<Event>>) {
impl Io {
fn check_association(&self, registry: &Registry, required: bool) -> io::Result<()> {
match self.cp {
- Some(ref cp) if !poll::selector(registry).same_port(cp) => {
- Err(io::Error::new(
- io::ErrorKind::AlreadyExists,
- "I/O source already registered with a different `Registry`"
- ))
- }
- None if required => {
- Err(io::Error::new(
- io::ErrorKind::NotFound,
- "I/O source not registered with `Registry`"
- ))
- }
+ Some(ref cp) if !poll::selector(registry).same_port(cp) => Err(io::Error::new(
+ io::ErrorKind::AlreadyExists,
+ "I/O source already registered with a different `Registry`",
+ )),
+ None if required => Err(io::Error::new(
+ io::ErrorKind::NotFound,
+ "I/O source not registered with `Registry`",
+ )),
_ => Ok(()),
}
}