Snap for 9626528 from 362f018cbb0bfc824e86114a960012bbe01e4964 to udc-release

Change-Id: I81601e591acb96d062614cd3b4895704cb1d11bc
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index c60d385..30e5027 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "0accf7dc22f197245e6a1aa84096262cd6f6e4d4"
+    "sha1": "7ed74bf478230a0cfa7543901f6be6df8bb3602e"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 660a924..eb6fed1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,7 +23,7 @@
     host_supported: true,
     crate_name: "mio",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.8.5",
+    cargo_pkg_version: "0.8.6",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
@@ -50,7 +50,7 @@
     host_supported: true,
     crate_name: "mio",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.8.5",
+    cargo_pkg_version: "0.8.6",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 10d9154..e45a2b3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,24 @@
+# 0.8.6
+
+## Added
+
+* `Interest::PRIORITY` on Linux and Android, to trigger `Event::is_priority`
+  (https://github.com/tokio-rs/mio/pull/1647).
+
+## Changed
+
+* Updated windows-sys to 0.45
+  (https://github.com/tokio-rs/mio/pull/1644).
+* We started testing with sanitizers on the CI
+  (https://github.com/tokio-rs/mio/pull/1648).
+
+## Fixed
+
+* A number of potential fd leaks when setup resulted in an error right after
+  creation (https://github.com/tokio-rs/mio/pull/1636).
+* Less truncating for timeout values in `Poll::poll`
+  (https://github.com/tokio-rs/mio/pull/1642).
+
 # 0.8.5
 
 ## Changed
diff --git a/Cargo.lock b/Cargo.lock
index 76cbc55..6a7d9ce 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -19,9 +19,9 @@
 
 [[package]]
 name = "getrandom"
-version = "0.2.7"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
 dependencies = [
  "cfg-if",
  "libc",
@@ -30,9 +30,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.126"
+version = "0.2.139"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
 
 [[package]]
 name = "log"
@@ -45,7 +45,7 @@
 
 [[package]]
 name = "mio"
-version = "0.8.5"
+version = "0.8.6"
 dependencies = [
  "env_logger",
  "libc",
@@ -57,9 +57,9 @@
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.16"
+version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "rand"
@@ -84,9 +84,9 @@
 
 [[package]]
 name = "rand_core"
-version = "0.6.3"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 dependencies = [
  "getrandom",
 ]
@@ -99,9 +99,18 @@
 
 [[package]]
 name = "windows-sys"
-version = "0.42.0"
+version = "0.45.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
 dependencies = [
  "windows_aarch64_gnullvm",
  "windows_aarch64_msvc",
@@ -114,42 +123,42 @@
 
 [[package]]
 name = "windows_aarch64_gnullvm"
-version = "0.42.0"
+version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.42.0"
+version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
+checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.42.0"
+version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
+checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.42.0"
+version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
+checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.42.0"
+version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.42.0"
+version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.42.0"
+version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
diff --git a/Cargo.toml b/Cargo.toml
index 7460010..fe4bc85 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
 [package]
 edition = "2018"
 name = "mio"
-version = "0.8.5"
+version = "0.8.6"
 authors = [
     "Carl Lerche <me@carllerche.com>",
     "Thomas de Zeeuw <thomasdezeeuw@gmail.com>",
@@ -26,7 +26,7 @@
     "src/**/*.rs",
     "examples/**/*.rs",
 ]
-description = "Lightweight non-blocking IO"
+description = "Lightweight non-blocking I/O."
 homepage = "https://github.com/tokio-rs/mio"
 readme = "README.md"
 keywords = [
@@ -116,7 +116,7 @@
 version = "0.2.121"
 
 [target."cfg(windows)".dependencies.windows-sys]
-version = "0.42"
+version = "0.45"
 features = [
     "Win32_Foundation",
     "Win32_Networking_WinSock",
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index c5052a7..84eb63b 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -4,14 +4,14 @@
 # When releasing to crates.io:
 # - Update CHANGELOG.md.
 # - Create git tag
-version       = "0.8.5"
+version       = "0.8.6"
 license       = "MIT"
 authors       = [
   "Carl Lerche <me@carllerche.com>",
   "Thomas de Zeeuw <thomasdezeeuw@gmail.com>",
   "Tokio Contributors <team@tokio.rs>",
 ]
-description   = "Lightweight non-blocking IO"
+description   = "Lightweight non-blocking I/O."
 homepage      = "https://github.com/tokio-rs/mio"
 repository    = "https://github.com/tokio-rs/mio"
 readme        = "README.md"
@@ -49,7 +49,7 @@
 libc = "0.2.121"
 
 [target.'cfg(windows)'.dependencies.windows-sys]
-version = "0.42"
+version = "0.45"
 features = [
   "Win32_Foundation",                 # Basic types eg HANDLE
   "Win32_Networking_WinSock",         # winsock2 types/functions
diff --git a/METADATA b/METADATA
index 5d0b7d4..11a32f7 100644
--- a/METADATA
+++ b/METADATA
@@ -3,7 +3,7 @@
 # For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
 
 name: "mio"
-description: "Lightweight non-blocking IO"
+description: "Lightweight non-blocking I/O."
 third_party {
   url {
     type: HOMEPAGE
@@ -11,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/mio/mio-0.8.5.crate"
+    value: "https://static.crates.io/crates/mio/mio-0.8.6.crate"
   }
-  version: "0.8.5"
+  version: "0.8.6"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2022
-    month: 12
-    day: 12
+    year: 2023
+    month: 2
+    day: 16
   }
 }
diff --git a/README.md b/README.md
index c17f3d3..bebd2af 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Mio – Metal IO
+# Mio – Metal I/O
 
 Mio is a fast, low-level I/O library for Rust focusing on non-blocking APIs and
 event notification for building high performance I/O apps with as little
@@ -20,10 +20,8 @@
 
 **API documentation**
 
-* [master](https://tokio-rs.github.io/mio/doc/mio/)
 * [v0.8](https://docs.rs/mio/^0.8)
 * [v0.7](https://docs.rs/mio/^0.7)
-* [v0.6](https://docs.rs/mio/^0.6)
 
 This is a low level library, if you are looking for something easier to get
 started with, see [Tokio](https://tokio.rs).
diff --git a/src/interest.rs b/src/interest.rs
index 0aa0bda..50d1bf0 100644
--- a/src/interest.rs
+++ b/src/interest.rs
@@ -20,18 +20,9 @@
 const READABLE: u8 = 0b0001;
 const WRITABLE: u8 = 0b0010;
 // The following are not available on all platforms.
-#[cfg_attr(
-    not(any(
-        target_os = "dragonfly",
-        target_os = "freebsd",
-        target_os = "ios",
-        target_os = "macos"
-    )),
-    allow(dead_code)
-)]
 const AIO: u8 = 0b0100;
-#[cfg_attr(not(target_os = "freebsd"), allow(dead_code))]
 const LIO: u8 = 0b1000;
+const PRIORITY: u8 = 0b10000;
 
 impl Interest {
     /// Returns a `Interest` set representing readable interests.
@@ -45,7 +36,7 @@
         target_os = "dragonfly",
         target_os = "freebsd",
         target_os = "ios",
-        target_os = "macos"
+        target_os = "macos",
     ))]
     pub const AIO: Interest = Interest(unsafe { NonZeroU8::new_unchecked(AIO) });
 
@@ -53,6 +44,10 @@
     #[cfg(target_os = "freebsd")]
     pub const LIO: Interest = Interest(unsafe { NonZeroU8::new_unchecked(LIO) });
 
+    /// Returns a `Interest` set representing priority completion interests.
+    #[cfg(any(target_os = "linux", target_os = "android"))]
+    pub const PRIORITY: Interest = Interest(unsafe { NonZeroU8::new_unchecked(PRIORITY) });
+
     /// Add together two `Interest`.
     ///
     /// This does the same thing as the `BitOr` implementation, but is a
@@ -104,15 +99,20 @@
         (self.0.get() & WRITABLE) != 0
     }
 
-    /// Returns true if `Interest` contains AIO readiness
+    /// Returns true if `Interest` contains AIO readiness.
     pub const fn is_aio(self) -> bool {
         (self.0.get() & AIO) != 0
     }
 
-    /// Returns true if `Interest` contains LIO readiness
+    /// Returns true if `Interest` contains LIO readiness.
     pub const fn is_lio(self) -> bool {
         (self.0.get() & LIO) != 0
     }
+
+    /// Returns true if `Interest` contains priority readiness.
+    pub const fn is_priority(self) -> bool {
+        (self.0.get() & PRIORITY) != 0
+    }
 }
 
 impl ops::BitOr for Interest {
@@ -152,7 +152,7 @@
             target_os = "dragonfly",
             target_os = "freebsd",
             target_os = "ios",
-            target_os = "macos"
+            target_os = "macos",
         ))]
         {
             if self.is_aio() {
@@ -173,6 +173,16 @@
                 one = true
             }
         }
+        #[cfg(any(target_os = "linux", target_os = "android"))]
+        {
+            if self.is_priority() {
+                if one {
+                    write!(fmt, " | ")?
+                }
+                write!(fmt, "PRIORITY")?;
+                one = true
+            }
+        }
         debug_assert!(one, "printing empty interests");
         Ok(())
     }
diff --git a/src/net/tcp/stream.rs b/src/net/tcp/stream.rs
index a7a9aa1..8a3f6a2 100644
--- a/src/net/tcp/stream.rs
+++ b/src/net/tcp/stream.rs
@@ -72,7 +72,7 @@
     ///     `ErrorKind::NotConnected` it means the stream is not yet connected,
     ///     go back to step 3. If it returns an address it means the stream is
     ///     connected, go to step 5. If another error is returned something
-    ///     whent wrong.
+    ///     went wrong.
     ///  5. Now the stream can be used.
     ///
     /// This may return a `WouldBlock` in which case the socket connection
diff --git a/src/sys/unix/net.rs b/src/sys/unix/net.rs
index 78f1387..2396ab9 100644
--- a/src/sys/unix/net.rs
+++ b/src/sys/unix/net.rs
@@ -20,43 +20,39 @@
         target_os = "illumos",
         target_os = "linux",
         target_os = "netbsd",
-        target_os = "openbsd"
+        target_os = "openbsd",
     ))]
     let socket_type = socket_type | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
 
-    // Gives a warning for platforms without SOCK_NONBLOCK.
-    #[allow(clippy::let_and_return)]
-    let socket = syscall!(socket(domain, socket_type, 0));
+    let socket = syscall!(socket(domain, socket_type, 0))?;
 
     // Mimick `libstd` and set `SO_NOSIGPIPE` on apple systems.
-    #[cfg(target_vendor = "apple")]
-    let socket = socket.and_then(|socket| {
-        syscall!(setsockopt(
-            socket,
-            libc::SOL_SOCKET,
-            libc::SO_NOSIGPIPE,
-            &1 as *const libc::c_int as *const libc::c_void,
-            size_of::<libc::c_int>() as libc::socklen_t
-        ))
-        .map(|_| socket)
-    });
+    #[cfg(any(target_os = "ios", target_os = "macos"))]
+    if let Err(err) = syscall!(setsockopt(
+        socket,
+        libc::SOL_SOCKET,
+        libc::SO_NOSIGPIPE,
+        &1 as *const libc::c_int as *const libc::c_void,
+        size_of::<libc::c_int>() as libc::socklen_t
+    )) {
+        let _ = syscall!(close(socket));
+        return Err(err);
+    }
 
     // Darwin doesn't have SOCK_NONBLOCK or SOCK_CLOEXEC.
     #[cfg(any(target_os = "ios", target_os = "macos"))]
-    let socket = socket.and_then(|socket| {
-        // For platforms that don't support flags in socket, we need to
-        // set the flags ourselves.
-        syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK))
-            .and_then(|_| syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC)).map(|_| socket))
-            .map_err(|e| {
-                // If either of the `fcntl` calls failed, ensure the socket is
-                // closed and return the error.
-                let _ = syscall!(close(socket));
-                e
-            })
-    });
+    {
+        if let Err(err) = syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK)) {
+            let _ = syscall!(close(socket));
+            return Err(err);
+        }
+        if let Err(err) = syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC)) {
+            let _ = syscall!(close(socket));
+            return Err(err);
+        }
+    }
 
-    socket
+    Ok(socket)
 }
 
 /// A type with the same memory layout as `libc::sockaddr`. Used in converting Rust level
@@ -96,7 +92,7 @@
                     target_os = "ios",
                     target_os = "macos",
                     target_os = "netbsd",
-                    target_os = "openbsd"
+                    target_os = "openbsd",
                 ))]
                 sin_len: 0,
             };
@@ -120,7 +116,7 @@
                     target_os = "ios",
                     target_os = "macos",
                     target_os = "netbsd",
-                    target_os = "openbsd"
+                    target_os = "openbsd",
                 ))]
                 sin6_len: 0,
                 #[cfg(target_os = "illumos")]
diff --git a/src/sys/unix/pipe.rs b/src/sys/unix/pipe.rs
index 7a95b96..7b7e4db 100644
--- a/src/sys/unix/pipe.rs
+++ b/src/sys/unix/pipe.rs
@@ -176,7 +176,7 @@
                 || libc::fcntl(*fd, libc::F_SETFD, libc::FD_CLOEXEC) != 0
             {
                 let err = io::Error::last_os_error();
-                // Don't leak file descriptors. Can't handle error though.
+                // Don't leak file descriptors. Can't handle closing error though.
                 let _ = libc::close(fds[0]);
                 let _ = libc::close(fds[1]);
                 return Err(err);
@@ -188,19 +188,20 @@
         target_os = "android",
         target_os = "dragonfly",
         target_os = "freebsd",
+        target_os = "illumos",
+        target_os = "ios",
         target_os = "linux",
+        target_os = "macos",
         target_os = "netbsd",
         target_os = "openbsd",
-        target_os = "ios",
-        target_os = "macos",
-        target_os = "illumos",
         target_os = "redox",
     )))]
     compile_error!("unsupported target for `mio::unix::pipe`");
 
-    // Safety: we just initialised the `fds` above.
+    // SAFETY: we just initialised the `fds` above.
     let r = unsafe { Receiver::from_raw_fd(fds[0]) };
     let w = unsafe { Sender::from_raw_fd(fds[1]) };
+
     Ok((w, r))
 }
 
diff --git a/src/sys/unix/selector/epoll.rs b/src/sys/unix/selector/epoll.rs
index 1256663..1809a2b 100644
--- a/src/sys/unix/selector/epoll.rs
+++ b/src/sys/unix/selector/epoll.rs
@@ -1,6 +1,6 @@
 use crate::{Interest, Token};
 
-use libc::{EPOLLET, EPOLLIN, EPOLLOUT, EPOLLRDHUP};
+use libc::{EPOLLET, EPOLLIN, EPOLLOUT, EPOLLPRI, EPOLLRDHUP};
 use log::error;
 use std::os::unix::io::{AsRawFd, RawFd};
 #[cfg(debug_assertions)]
@@ -88,16 +88,11 @@
 
         let timeout = timeout
             .map(|to| {
-                let to_ms = to.as_millis();
-                // as_millis() truncates, so round up to 1 ms as the documentation says can happen.
-                // This avoids turning submillisecond timeouts into immediate returns unless the
-                // caller explicitly requests that by specifying a zero timeout.
-                let to_ms = to_ms
-                    + if to_ms == 0 && to.subsec_nanos() != 0 {
-                        1
-                    } else {
-                        0
-                    };
+                // `Duration::as_millis` truncates, so round up. This avoids
+                // turning sub-millisecond timeouts into a zero timeout, unless
+                // the caller explicitly requests that by specifying a zero
+                // timeout.
+                let to_ms = (to + Duration::from_nanos(999_999)).as_millis();
                 cmp::min(MAX_SAFE_TIMEOUT, to_ms) as libc::c_int
             })
             .unwrap_or(-1);
@@ -182,6 +177,10 @@
         kind |= EPOLLOUT;
     }
 
+    if interests.is_priority() {
+        kind |= EPOLLPRI;
+    }
+
     kind as u32
 }
 
diff --git a/src/sys/unix/selector/kqueue.rs b/src/sys/unix/selector/kqueue.rs
index 0be4281..1eedec0 100644
--- a/src/sys/unix/selector/kqueue.rs
+++ b/src/sys/unix/selector/kqueue.rs
@@ -21,7 +21,7 @@
 // Type of the `filter` field in the `kevent` structure.
 #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
 type Filter = libc::c_short;
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
 type Filter = i16;
 #[cfg(target_os = "netbsd")]
 type Filter = u32;
@@ -29,7 +29,7 @@
 // Type of the `flags` field in the `kevent` structure.
 #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
 type Flags = libc::c_ushort;
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "ios", target_os = "macos"))]
 type Flags = u16;
 #[cfg(target_os = "netbsd")]
 type Flags = u32;
@@ -63,15 +63,17 @@
 
 impl Selector {
     pub fn new() -> io::Result<Selector> {
-        syscall!(kqueue())
-            .and_then(|kq| syscall!(fcntl(kq, libc::F_SETFD, libc::FD_CLOEXEC)).map(|_| kq))
-            .map(|kq| Selector {
-                #[cfg(debug_assertions)]
-                id: NEXT_ID.fetch_add(1, Ordering::Relaxed),
-                kq,
-                #[cfg(debug_assertions)]
-                has_waker: AtomicBool::new(false),
-            })
+        let kq = syscall!(kqueue())?;
+        let selector = Selector {
+            #[cfg(debug_assertions)]
+            id: NEXT_ID.fetch_add(1, Ordering::Relaxed),
+            kq,
+            #[cfg(debug_assertions)]
+            has_waker: AtomicBool::new(false),
+        };
+
+        syscall!(fcntl(kq, libc::F_SETFD, libc::FD_CLOEXEC))?;
+        Ok(selector)
     }
 
     pub fn try_clone(&self) -> io::Result<Selector> {
@@ -403,7 +405,7 @@
             target_os = "dragonfly",
             target_os = "freebsd",
             target_os = "ios",
-            target_os = "macos"
+            target_os = "macos",
         ))]
         {
             event.filter == libc::EVFILT_AIO
@@ -412,7 +414,7 @@
             target_os = "dragonfly",
             target_os = "freebsd",
             target_os = "ios",
-            target_os = "macos"
+            target_os = "macos",
         )))]
         {
             false
@@ -448,7 +450,7 @@
                 target_os = "freebsd",
                 target_os = "dragonfly",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::EVFILT_FS,
             #[cfg(target_os = "freebsd")]
@@ -457,7 +459,7 @@
                 target_os = "freebsd",
                 target_os = "dragonfly",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::EVFILT_USER,
             #[cfg(target_os = "freebsd")]
@@ -514,49 +516,49 @@
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::NOTE_TRIGGER,
             #[cfg(any(
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::NOTE_FFNOP,
             #[cfg(any(
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::NOTE_FFAND,
             #[cfg(any(
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::NOTE_FFOR,
             #[cfg(any(
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::NOTE_FFCOPY,
             #[cfg(any(
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::NOTE_FFCTRLMASK,
             #[cfg(any(
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "ios",
-                target_os = "macos"
+                target_os = "macos",
             ))]
             libc::NOTE_FFLAGSMASK,
             libc::NOTE_LOWAT,
@@ -591,21 +593,21 @@
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "netbsd",
-                target_os = "openbsd"
+                target_os = "openbsd",
             ))]
             libc::NOTE_TRACK,
             #[cfg(any(
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "netbsd",
-                target_os = "openbsd"
+                target_os = "openbsd",
             ))]
             libc::NOTE_TRACKERR,
             #[cfg(any(
                 target_os = "dragonfly",
                 target_os = "freebsd",
                 target_os = "netbsd",
-                target_os = "openbsd"
+                target_os = "openbsd",
             ))]
             libc::NOTE_CHILD,
             #[cfg(any(target_os = "ios", target_os = "macos"))]
@@ -633,7 +635,6 @@
             #[cfg(any(target_os = "freebsd", target_os = "ios", target_os = "macos"))]
             libc::NOTE_NSECONDS,
             #[cfg(any(target_os = "ios", target_os = "macos"))]
-            #[cfg(any(target_os = "freebsd", target_os = "ios", target_os = "macos"))]
             libc::NOTE_ABSOLUTE,
             #[cfg(any(target_os = "ios", target_os = "macos"))]
             libc::NOTE_LEEWAY,
diff --git a/src/sys/unix/selector/mod.rs b/src/sys/unix/selector/mod.rs
index 9ae4c14..c06c7b1 100644
--- a/src/sys/unix/selector/mod.rs
+++ b/src/sys/unix/selector/mod.rs
@@ -17,20 +17,20 @@
 #[cfg(any(
     target_os = "dragonfly",
     target_os = "freebsd",
+    target_os = "netbsd",
+    target_os = "openbsd",
     target_os = "ios",
     target_os = "macos",
-    target_os = "netbsd",
-    target_os = "openbsd"
 ))]
 mod kqueue;
 
 #[cfg(any(
     target_os = "dragonfly",
     target_os = "freebsd",
+    target_os = "netbsd",
+    target_os = "openbsd",
     target_os = "ios",
     target_os = "macos",
-    target_os = "netbsd",
-    target_os = "openbsd"
 ))]
 pub(crate) use self::kqueue::{event, Event, Events, Selector};
 
diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs
index c4d7e94..9513cc0 100644
--- a/src/sys/unix/tcp.rs
+++ b/src/sys/unix/tcp.rs
@@ -40,7 +40,7 @@
 }
 
 pub(crate) fn set_reuseaddr(socket: &net::TcpListener, reuseaddr: bool) -> io::Result<()> {
-    let val: libc::c_int = if reuseaddr { 1 } else { 0 };
+    let val: libc::c_int = i32::from(reuseaddr);
     syscall!(setsockopt(
         socket.as_raw_fd(),
         libc::SOL_SOCKET,
@@ -60,16 +60,13 @@
     #[cfg(any(
         // 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"
-        ),
+        all(not(target_arch="x86"), target_os = "android"),
         target_os = "dragonfly",
         target_os = "freebsd",
         target_os = "illumos",
         target_os = "linux",
         target_os = "netbsd",
-        target_os = "openbsd"
+        target_os = "openbsd",
     ))]
     let stream = {
         syscall!(accept4(
@@ -85,10 +82,10 @@
     // OSes inherit the non-blocking flag from the listener, so we just have to
     // set `CLOEXEC`.
     #[cfg(any(
-        all(target_arch = "x86", target_os = "android"),
         target_os = "ios",
         target_os = "macos",
-        target_os = "redox"
+        target_os = "redox",
+        all(target_arch = "x86", target_os = "android"),
     ))]
     let stream = {
         syscall!(accept(
diff --git a/src/sys/unix/udp.rs b/src/sys/unix/udp.rs
index 5a97cbd..843ae88 100644
--- a/src/sys/unix/udp.rs
+++ b/src/sys/unix/udp.rs
@@ -6,21 +6,13 @@
 use std::os::unix::io::{AsRawFd, FromRawFd};
 
 pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
-    // Gives a warning for non Apple platforms.
-    #[allow(clippy::let_and_return)]
-    let socket = new_ip_socket(addr, libc::SOCK_DGRAM);
+    let fd = new_ip_socket(addr, libc::SOCK_DGRAM)?;
+    let socket = unsafe { net::UdpSocket::from_raw_fd(fd) };
 
-    socket.and_then(|socket| {
-        let (raw_addr, raw_addr_length) = socket_addr(&addr);
-        syscall!(bind(socket, raw_addr.as_ptr(), raw_addr_length))
-            .map_err(|err| {
-                // Close the socket if we hit an error, ignoring the error
-                // from closing since we can't pass back two errors.
-                let _ = unsafe { libc::close(socket) };
-                err
-            })
-            .map(|_| unsafe { net::UdpSocket::from_raw_fd(socket) })
-    })
+    let (raw_addr, raw_addr_length) = socket_addr(&addr);
+    syscall!(bind(fd, raw_addr.as_ptr(), raw_addr_length))?;
+
+    Ok(socket)
 }
 
 pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {
diff --git a/src/sys/unix/uds/datagram.rs b/src/sys/unix/uds/datagram.rs
index d3e5314..a5ada72 100644
--- a/src/sys/unix/uds/datagram.rs
+++ b/src/sys/unix/uds/datagram.rs
@@ -7,18 +7,18 @@
 use std::path::Path;
 
 pub(crate) fn bind(path: &Path) -> io::Result<net::UnixDatagram> {
-    let fd = new_socket(libc::AF_UNIX, libc::SOCK_DGRAM)?;
-    // Ensure the fd is closed.
-    let socket = unsafe { net::UnixDatagram::from_raw_fd(fd) };
     let (sockaddr, socklen) = socket_addr(path)?;
     let sockaddr = &sockaddr as *const libc::sockaddr_un as *const _;
-    syscall!(bind(fd, sockaddr, socklen))?;
+
+    let socket = unbound()?;
+    syscall!(bind(socket.as_raw_fd(), sockaddr, socklen))?;
+
     Ok(socket)
 }
 
 pub(crate) fn unbound() -> io::Result<net::UnixDatagram> {
-    new_socket(libc::AF_UNIX, libc::SOCK_DGRAM)
-        .map(|socket| unsafe { net::UnixDatagram::from_raw_fd(socket) })
+    let fd = new_socket(libc::AF_UNIX, libc::SOCK_DGRAM)?;
+    Ok(unsafe { net::UnixDatagram::from_raw_fd(fd) })
 }
 
 pub(crate) fn pair() -> io::Result<(net::UnixDatagram, net::UnixDatagram)> {
diff --git a/src/sys/unix/uds/listener.rs b/src/sys/unix/uds/listener.rs
index 79bd14e..3e33b30 100644
--- a/src/sys/unix/uds/listener.rs
+++ b/src/sys/unix/uds/listener.rs
@@ -7,19 +7,15 @@
 use std::{io, mem};
 
 pub(crate) fn bind(path: &Path) -> io::Result<net::UnixListener> {
-    let socket = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
     let (sockaddr, socklen) = socket_addr(path)?;
     let sockaddr = &sockaddr as *const libc::sockaddr_un as *const libc::sockaddr;
 
-    syscall!(bind(socket, sockaddr, socklen))
-        .and_then(|_| syscall!(listen(socket, 1024)))
-        .map_err(|err| {
-            // Close the socket if we hit an error, ignoring the error from
-            // closing since we can't pass back two errors.
-            let _ = unsafe { libc::close(socket) };
-            err
-        })
-        .map(|_| unsafe { net::UnixListener::from_raw_fd(socket) })
+    let fd = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
+    let socket = unsafe { net::UnixListener::from_raw_fd(fd) };
+    syscall!(bind(fd, sockaddr, socklen))?;
+    syscall!(listen(fd, 1024))?;
+
+    Ok(socket)
 }
 
 pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, SocketAddr)> {
@@ -45,10 +41,7 @@
         target_os = "redox",
         // 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"
-        )
+        all(target_arch = "x86", target_os = "android"),
     )))]
     let socket = {
         let flags = libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
@@ -62,10 +55,10 @@
     };
 
     #[cfg(any(
-        target_os = "ios",
-        target_os = "macos",
         target_os = "netbsd",
         target_os = "redox",
+        target_os = "ios",
+        target_os = "macos",
         all(target_arch = "x86", target_os = "android")
     ))]
     let socket = syscall!(accept(
diff --git a/src/sys/unix/uds/stream.rs b/src/sys/unix/uds/stream.rs
index 9ae4867..461917c 100644
--- a/src/sys/unix/uds/stream.rs
+++ b/src/sys/unix/uds/stream.rs
@@ -7,23 +7,18 @@
 use std::path::Path;
 
 pub(crate) fn connect(path: &Path) -> io::Result<net::UnixStream> {
-    let socket = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
     let (sockaddr, socklen) = socket_addr(path)?;
     let sockaddr = &sockaddr as *const libc::sockaddr_un as *const libc::sockaddr;
 
-    match syscall!(connect(socket, sockaddr, socklen)) {
+    let fd = new_socket(libc::AF_UNIX, libc::SOCK_STREAM)?;
+    let socket = unsafe { net::UnixStream::from_raw_fd(fd) };
+    match syscall!(connect(fd, sockaddr, socklen)) {
         Ok(_) => {}
         Err(ref err) if err.raw_os_error() == Some(libc::EINPROGRESS) => {}
-        Err(e) => {
-            // Close the socket if we hit an error, ignoring the error
-            // from closing since we can't pass back two errors.
-            let _ = unsafe { libc::close(socket) };
-
-            return Err(e);
-        }
+        Err(e) => return Err(e),
     }
 
-    Ok(unsafe { net::UnixStream::from_raw_fd(socket) })
+    Ok(socket)
 }
 
 pub(crate) fn pair() -> io::Result<(net::UnixStream, net::UnixStream)> {
diff --git a/src/sys/unix/waker.rs b/src/sys/unix/waker.rs
index de88e31..d8764c2 100644
--- a/src/sys/unix/waker.rs
+++ b/src/sys/unix/waker.rs
@@ -20,14 +20,11 @@
 
     impl Waker {
         pub fn new(selector: &Selector, token: Token) -> io::Result<Waker> {
-            syscall!(eventfd(0, libc::EFD_CLOEXEC | libc::EFD_NONBLOCK)).and_then(|fd| {
-                // Turn the file descriptor into a file first so we're ensured
-                // it's closed when dropped, e.g. when register below fails.
-                let file = unsafe { File::from_raw_fd(fd) };
-                selector
-                    .register(fd, token, Interest::READABLE)
-                    .map(|()| Waker { fd: file })
-            })
+            let fd = syscall!(eventfd(0, libc::EFD_CLOEXEC | libc::EFD_NONBLOCK))?;
+            let file = unsafe { File::from_raw_fd(fd) };
+
+            selector.register(fd, token, Interest::READABLE)?;
+            Ok(Waker { fd: file })
         }
 
         pub fn wake(&self) -> io::Result<()> {
@@ -82,11 +79,9 @@
 
     impl Waker {
         pub fn new(selector: &Selector, token: Token) -> io::Result<Waker> {
-            selector.try_clone().and_then(|selector| {
-                selector
-                    .setup_waker(token)
-                    .map(|()| Waker { selector, token })
-            })
+            let selector = selector.try_clone()?;
+            selector.setup_waker(token)?;
+            Ok(Waker { selector, token })
         }
 
         pub fn wake(&self) -> io::Result<()> {
@@ -127,13 +122,11 @@
         pub fn new(selector: &Selector, token: Token) -> io::Result<Waker> {
             let mut fds = [-1; 2];
             syscall!(pipe2(fds.as_mut_ptr(), libc::O_NONBLOCK | libc::O_CLOEXEC))?;
-            // Turn the file descriptors into files first so we're ensured
-            // they're closed when dropped, e.g. when register below fails.
             let sender = unsafe { File::from_raw_fd(fds[1]) };
             let receiver = unsafe { File::from_raw_fd(fds[0]) };
-            selector
-                .register(fds[0], token, Interest::READABLE)
-                .map(|()| Waker { sender, receiver })
+
+            selector.register(fds[0], token, Interest::READABLE)?;
+            Ok(Waker { sender, receiver })
         }
 
         pub fn wake(&self) -> io::Result<()> {
diff --git a/src/sys/windows/iocp.rs b/src/sys/windows/iocp.rs
index 142b6fc..262c8f2 100644
--- a/src/sys/windows/iocp.rs
+++ b/src/sys/windows/iocp.rs
@@ -224,17 +224,12 @@
 #[inline]
 fn duration_millis(dur: Option<Duration>) -> u32 {
     if let Some(dur) = dur {
-        let dur_ms = dur.as_millis();
-        // as_millis() truncates, so round nonzero <1ms timeouts up to 1ms.  This avoids turning
-        // submillisecond timeouts into immediate reutrns unless the caller explictly requests that
-        // by specifiying a zero timeout.
-        let dur_ms = dur_ms
-            + if dur_ms == 0 && dur.subsec_nanos() != 0 {
-                1
-            } else {
-                0
-            };
-        std::cmp::min(dur_ms, u32::MAX as u128) as u32
+        // `Duration::as_millis` truncates, so round up. This avoids
+        // turning sub-millisecond timeouts into a zero timeout, unless
+        // the caller explicitly requests that by specifying a zero
+        // timeout.
+        let dur_ms = (dur + Duration::from_nanos(999_999)).as_millis();
+        cmp::min(dur_ms, u32::MAX as u128) as u32
     } else {
         u32::MAX
     }
diff --git a/src/sys/windows/net.rs b/src/sys/windows/net.rs
index 102ba79..44f459a 100644
--- a/src/sys/windows/net.rs
+++ b/src/sys/windows/net.rs
@@ -4,12 +4,13 @@
 use std::sync::Once;
 
 use windows_sys::Win32::Networking::WinSock::{
-    ioctlsocket, socket, AF_INET, AF_INET6, FIONBIO, IN6_ADDR, IN6_ADDR_0, INVALID_SOCKET, IN_ADDR,
-    IN_ADDR_0, SOCKADDR, SOCKADDR_IN, SOCKADDR_IN6, SOCKADDR_IN6_0, SOCKET,
+    closesocket, ioctlsocket, socket, AF_INET, AF_INET6, FIONBIO, IN6_ADDR, IN6_ADDR_0,
+    INVALID_SOCKET, IN_ADDR, IN_ADDR_0, SOCKADDR, SOCKADDR_IN, SOCKADDR_IN6, SOCKADDR_IN6_0,
+    SOCKET,
 };
 
 /// Initialise the network stack for Windows.
-pub(crate) fn init() {
+fn init() {
     static INIT: Once = Once::new();
     INIT.call_once(|| {
         // Let standard library call `WSAStartup` for us, we can't do it
@@ -26,18 +27,24 @@
         SocketAddr::V6(..) => AF_INET6,
     };
 
-    new_socket(domain, socket_type)
+    new_socket(domain.into(), socket_type)
 }
 
 pub(crate) fn new_socket(domain: u32, socket_type: u16) -> io::Result<SOCKET> {
-    syscall!(
+    init();
+
+    let socket = syscall!(
         socket(domain as i32, socket_type as i32, 0),
         PartialEq::eq,
         INVALID_SOCKET
-    )
-    .and_then(|socket| {
-        syscall!(ioctlsocket(socket, FIONBIO, &mut 1), PartialEq::ne, 0).map(|_| socket as SOCKET)
-    })
+    )?;
+
+    if let Err(err) = syscall!(ioctlsocket(socket, FIONBIO, &mut 1), PartialEq::ne, 0) {
+        let _ = unsafe { closesocket(socket) };
+        return Err(err);
+    }
+
+    Ok(socket as SOCKET)
 }
 
 /// A type with the same memory layout as `SOCKADDR`. Used in converting Rust level
diff --git a/src/sys/windows/tcp.rs b/src/sys/windows/tcp.rs
index 533074b..addd1e8 100644
--- a/src/sys/windows/tcp.rs
+++ b/src/sys/windows/tcp.rs
@@ -2,19 +2,12 @@
 use std::net::{self, SocketAddr};
 use std::os::windows::io::AsRawSocket;
 
-use windows_sys::Win32::Networking::WinSock::{
-    self, AF_INET, AF_INET6, SOCKET, SOCKET_ERROR, SOCK_STREAM,
-};
+use windows_sys::Win32::Networking::WinSock::{self, SOCKET, SOCKET_ERROR, SOCK_STREAM};
 
-use crate::sys::windows::net::{init, new_socket, socket_addr};
+use crate::sys::windows::net::{new_ip_socket, socket_addr};
 
 pub(crate) fn new_for_addr(address: SocketAddr) -> io::Result<SOCKET> {
-    init();
-    let domain = match address {
-        SocketAddr::V4(_) => AF_INET,
-        SocketAddr::V6(_) => AF_INET6,
-    };
-    new_socket(domain, SOCK_STREAM)
+    new_ip_socket(address, SOCK_STREAM)
 }
 
 pub(crate) fn bind(socket: &net::TcpListener, addr: SocketAddr) -> io::Result<()> {
diff --git a/src/sys/windows/udp.rs b/src/sys/windows/udp.rs
index 91516cc..87e269f 100644
--- a/src/sys/windows/udp.rs
+++ b/src/sys/windows/udp.rs
@@ -4,28 +4,23 @@
 use std::os::windows::io::{AsRawSocket, FromRawSocket};
 use std::os::windows::raw::SOCKET as StdSocket; // windows-sys uses usize, stdlib uses u32/u64.
 
-use crate::sys::windows::net::{init, new_ip_socket, socket_addr};
+use crate::sys::windows::net::{new_ip_socket, socket_addr};
 use windows_sys::Win32::Networking::WinSock::{
-    bind as win_bind, closesocket, getsockopt, IPPROTO_IPV6, IPV6_V6ONLY, SOCKET_ERROR, SOCK_DGRAM,
+    bind as win_bind, getsockopt, IPPROTO_IPV6, IPV6_V6ONLY, SOCKET_ERROR, SOCK_DGRAM,
 };
 
 pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
-    init();
-    new_ip_socket(addr, SOCK_DGRAM).and_then(|socket| {
-        let (raw_addr, raw_addr_length) = socket_addr(&addr);
-        syscall!(
-            win_bind(socket, raw_addr.as_ptr(), raw_addr_length,),
-            PartialEq::eq,
-            SOCKET_ERROR
-        )
-        .map_err(|err| {
-            // Close the socket if we hit an error, ignoring the error
-            // from closing since we can't pass back two errors.
-            let _ = unsafe { closesocket(socket) };
-            err
-        })
-        .map(|_| unsafe { net::UdpSocket::from_raw_socket(socket as StdSocket) })
-    })
+    let raw_socket = new_ip_socket(addr, SOCK_DGRAM)?;
+    let socket = unsafe { net::UdpSocket::from_raw_socket(raw_socket as StdSocket) };
+
+    let (raw_addr, raw_addr_length) = socket_addr(&addr);
+    syscall!(
+        win_bind(raw_socket, raw_addr.as_ptr(), raw_addr_length),
+        PartialEq::eq,
+        SOCKET_ERROR
+    )?;
+
+    Ok(socket)
 }
 
 pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {