diff options
-rw-r--r-- | .cargo_vcs_info.json | 5 | ||||
-rw-r--r-- | Android.bp | 2 | ||||
-rw-r--r-- | CHANGELOG.md | 12 | ||||
-rw-r--r-- | Cargo.lock | 15 | ||||
-rw-r--r-- | Cargo.toml | 10 | ||||
-rw-r--r-- | Cargo.toml.orig | 6 | ||||
-rw-r--r-- | METADATA | 14 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/net/tcp/socket.rs | 6 | ||||
-rw-r--r-- | src/sys/shell/tcp.rs | 5 | ||||
-rw-r--r-- | src/sys/unix/tcp.rs | 18 | ||||
-rw-r--r-- | src/sys/unix/uds/socketaddr.rs | 2 | ||||
-rw-r--r-- | src/sys/windows/selector.rs | 43 | ||||
-rw-r--r-- | src/sys/windows/tcp.rs | 34 |
14 files changed, 111 insertions, 63 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json new file mode 100644 index 0000000..24a92d4 --- /dev/null +++ b/.cargo_vcs_info.json @@ -0,0 +1,5 @@ +{ + "git": { + "sha1": "d40494bf6a9d5437207671282aa1be6b93a964cd" + } +} @@ -20,5 +20,5 @@ rust_library { // dependent_library ["feature_list"] // cfg-if-0.1.10 -// libc-0.2.73 "default,std" +// libc-0.2.80 "default,std" // log-0.4.11 "std" diff --git a/CHANGELOG.md b/CHANGELOG.md index 12cc92d..5827f0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# 0.7.4 + +## Fixes + +* lost "socket closed" events on windows + (https://github.com/tokio-rs/mio/commit/50c299aca56c4a26e5ed20c283007239fbe6a7a7) + +## Added + +* `TcpSocket::set_linger()` configures SO_LINGER + (https://github.com/tokio-rs/mio/commit/3b4096565c1a879f651b8f8282ecdcbdbd5c92d3) + # 0.7.3 ## Added @@ -38,15 +38,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.3" +version = "0.7.4" dependencies = [ "env_logger", "libc", "log", "miow", - "net2", "ntapi", "rand", + "socket2", "winapi", ] @@ -61,17 +61,6 @@ dependencies = [ ] [[package]] -name = "net2" -version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" -dependencies = [ - "cfg-if", - "libc", - "winapi", -] - -[[package]] name = "ntapi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -13,12 +13,12 @@ [package] edition = "2018" name = "mio" -version = "0.7.3" +version = "0.7.4" authors = ["Carl Lerche <me@carllerche.com>"] include = ["Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", "src/**/*.rs", "examples/**/*.rs"] description = "Lightweight non-blocking IO" homepage = "https://github.com/tokio-rs/mio" -documentation = "https://docs.rs/mio/0.7.3" +documentation = "https://docs.rs/mio/0.7.4" readme = "README.md" keywords = ["io", "async", "non-blocking"] categories = ["asynchronous"] @@ -44,12 +44,12 @@ version = "0.4.8" version = "0.6.2" default-features = false -[dev-dependencies.net2] -version = "0.2.33" - [dev-dependencies.rand] version = "0.4" +[dev-dependencies.socket2] +version = "0.3.15" + [features] default = [] extra-docs = [] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 5206a44..ce99d1c 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -6,11 +6,11 @@ name = "mio" # - Update CHANGELOG.md. # - Update doc URL. # - Create git tag -version = "0.7.3" +version = "0.7.4" license = "MIT" authors = ["Carl Lerche <me@carllerche.com>"] description = "Lightweight non-blocking IO" -documentation = "https://docs.rs/mio/0.7.3" +documentation = "https://docs.rs/mio/0.7.4" homepage = "https://github.com/tokio-rs/mio" repository = "https://github.com/tokio-rs/mio" readme = "README.md" @@ -47,8 +47,8 @@ ntapi = "0.3" [dev-dependencies] env_logger = { version = "0.6.2", default-features = false } -net2 = "0.2.33" rand = "0.4" +socket2 = "0.3.15" [package.metadata.docs.rs] all-features = true @@ -1,7 +1,5 @@ name: "mio" -description: - "Lightweight non-blocking IO" - +description: "Lightweight non-blocking IO" third_party { url { type: HOMEPAGE @@ -9,9 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/mio/mio-0.7.3.crate" + value: "https://static.crates.io/crates/mio/mio-0.7.4.crate" } - version: "0.7.3" - last_upgrade_date { year: 2020 month: 10 day: 16 } + version: "0.7.4" license_type: NOTICE + last_upgrade_date { + year: 2020 + month: 10 + day: 26 + } } @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/mio/0.7.3")] +#![doc(html_root_url = "https://docs.rs/mio/0.7.4")] #![deny( missing_docs, missing_debug_implementations, diff --git a/src/net/tcp/socket.rs b/src/net/tcp/socket.rs index 0094de9..a91f665 100644 --- a/src/net/tcp/socket.rs +++ b/src/net/tcp/socket.rs @@ -4,6 +4,7 @@ use crate::sys; use std::io; use std::mem; use std::net::SocketAddr; +use std::time::Duration; #[cfg(unix)] use std::os::unix::io::{AsRawFd, RawFd, FromRawFd}; #[cfg(windows)] @@ -80,6 +81,11 @@ impl TcpSocket { pub fn set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()> { sys::tcp::set_reuseaddr(self.sys, reuseaddr) } + + /// Sets the value of `SO_LINGER` on this socket. + pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> { + sys::tcp::set_linger(self.sys, dur) + } } impl Drop for TcpSocket { diff --git a/src/sys/shell/tcp.rs b/src/sys/shell/tcp.rs index 963fccb..de1520b 100644 --- a/src/sys/shell/tcp.rs +++ b/src/sys/shell/tcp.rs @@ -1,5 +1,6 @@ use std::io; use std::net::{self, SocketAddr}; +use std::time::Duration; pub(crate) type TcpSocket = i32; @@ -31,6 +32,10 @@ pub(crate) fn set_reuseaddr(_: TcpSocket, _: bool) -> io::Result<()> { os_required!(); } +pub(crate) fn set_linger(_: TcpSocket, _: Option<Duration>) -> io::Result<()> { + os_required!(); +} + pub fn accept(_: &net::TcpListener) -> io::Result<(net::TcpStream, SocketAddr)> { os_required!(); } diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs index 9d59632..81b371b 100644 --- a/src/sys/unix/tcp.rs +++ b/src/sys/unix/tcp.rs @@ -1,6 +1,7 @@ use std::io; use std::mem::{size_of, MaybeUninit}; use std::net::{self, SocketAddr}; +use std::time::Duration; use std::os::unix::io::{AsRawFd, FromRawFd}; use crate::sys::unix::net::{new_socket, socket_addr, to_socket_addr}; @@ -54,8 +55,21 @@ pub(crate) fn set_reuseaddr(socket: TcpSocket, reuseaddr: bool) -> io::Result<() libc::SO_REUSEADDR, &val as *const libc::c_int as *const libc::c_void, size_of::<libc::c_int>() as libc::socklen_t, - ))?; - Ok(()) + )).map(|_| ()) +} + +pub(crate) fn set_linger(socket: TcpSocket, dur: Option<Duration>) -> io::Result<()> { + let val: libc::linger = libc::linger { + l_onoff: if dur.is_some() { 1 } else { 0 }, + l_linger: dur.map(|dur| dur.as_secs() as libc::c_int).unwrap_or_default(), + }; + syscall!(setsockopt( + socket, + libc::SOL_SOCKET, + libc::SO_LINGER, + &val as *const libc::linger as *const libc::c_void, + size_of::<libc::linger>() as libc::socklen_t, + )).map(|_| ()) } pub fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, SocketAddr)> { diff --git a/src/sys/unix/uds/socketaddr.rs b/src/sys/unix/uds/socketaddr.rs index 69f311a..ddfa2f0 100644 --- a/src/sys/unix/uds/socketaddr.rs +++ b/src/sys/unix/uds/socketaddr.rs @@ -74,6 +74,8 @@ cfg_os_poll! { /// Documentation reflected in [`SocketAddr`] /// /// [`SocketAddr`]: std::os::unix::net::SocketAddr + // FIXME: The matches macro requires rust 1.42.0 and we still support 1.39.0 + #[allow(clippy::match_like_matches_macro)] pub fn is_unnamed(&self) -> bool { if let AddressKind::Unnamed = self.address() { true diff --git a/src/sys/windows/selector.rs b/src/sys/windows/selector.rs index 792a5c5..4a38300 100644 --- a/src/sys/windows/selector.rs +++ b/src/sys/windows/selector.rs @@ -1,11 +1,14 @@ use super::afd::{self, Afd, AfdPollInfo}; use super::io_status_block::IoStatusBlock; use super::Event; -use crate::sys::event::{ - ERROR_FLAGS, READABLE_FLAGS, READ_CLOSED_FLAGS, WRITABLE_FLAGS, WRITE_CLOSED_FLAGS, -}; use crate::sys::Events; -use crate::Interest; + +cfg_net! { + use crate::sys::event::{ + ERROR_FLAGS, READABLE_FLAGS, READ_CLOSED_FLAGS, WRITABLE_FLAGS, WRITE_CLOSED_FLAGS, + }; + use crate::Interest; +} use miow::iocp::{CompletionPort, CompletionStatus}; use std::collections::VecDeque; @@ -226,15 +229,7 @@ impl SockState { // In mio, we have to simulate Edge-triggered behavior to match API usage. // The strategy here is to intercept all read/write from user that could cause WouldBlock usage, // then reregister the socket to reset the interests. - - // Reset readable event - if (afd_events & interests_to_afd_flags(Interest::READABLE)) != 0 { - self.user_evts &= !(interests_to_afd_flags(Interest::READABLE)); - } - // Reset writable event - if (afd_events & interests_to_afd_flags(Interest::WRITABLE)) != 0 { - self.user_evts &= !interests_to_afd_flags(Interest::WRITABLE); - } + self.user_evts &= !afd_events; Some(Event { data: self.user_data, @@ -730,16 +725,18 @@ impl Drop for SelectorInner { } } -fn interests_to_afd_flags(interests: Interest) -> u32 { - let mut flags = 0; +cfg_net! { + fn interests_to_afd_flags(interests: Interest) -> u32 { + let mut flags = 0; - if interests.is_readable() { - flags |= READABLE_FLAGS | READ_CLOSED_FLAGS | ERROR_FLAGS; - } + if interests.is_readable() { + flags |= READABLE_FLAGS | READ_CLOSED_FLAGS | ERROR_FLAGS; + } - if interests.is_writable() { - flags |= WRITABLE_FLAGS | WRITE_CLOSED_FLAGS | ERROR_FLAGS; - } + if interests.is_writable() { + flags |= WRITABLE_FLAGS | WRITE_CLOSED_FLAGS | ERROR_FLAGS; + } - flags -} + flags + } +}
\ No newline at end of file diff --git a/src/sys/windows/tcp.rs b/src/sys/windows/tcp.rs index c5b0410..46ac1ac 100644 --- a/src/sys/windows/tcp.rs +++ b/src/sys/windows/tcp.rs @@ -1,11 +1,15 @@ use std::io; +use std::mem::size_of; use std::net::{self, SocketAddr}; +use std::time::Duration; use std::os::windows::io::FromRawSocket; use std::os::windows::raw::SOCKET as StdSocket; // winapi uses usize, stdlib uses u32/u64. +use winapi::ctypes::{c_char, c_int, c_ushort}; +use winapi::shared::minwindef::{BOOL, TRUE, FALSE}; use winapi::um::winsock2::{ - self, - closesocket, PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, SOCK_STREAM, + self, closesocket, linger, setsockopt, PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, + SOCK_STREAM, SOL_SOCKET, SO_LINGER, SO_REUSEADDR, }; use crate::sys::windows::net::{init, new_socket, socket_addr}; @@ -69,11 +73,6 @@ pub(crate) fn close(socket: TcpSocket) { } pub(crate) fn set_reuseaddr(socket: TcpSocket, reuseaddr: bool) -> io::Result<()> { - use winapi::ctypes::{c_char, c_int}; - use winapi::shared::minwindef::{BOOL, TRUE, FALSE}; - use winapi::um::winsock2::{setsockopt, SOCKET_ERROR, SO_REUSEADDR, SOL_SOCKET}; - use std::mem::size_of; - let val: BOOL = if reuseaddr { TRUE } else { FALSE }; match unsafe { setsockopt( @@ -83,9 +82,26 @@ pub(crate) fn set_reuseaddr(socket: TcpSocket, reuseaddr: bool) -> io::Result<() &val as *const _ as *const c_char, size_of::<BOOL>() as c_int, ) } { - 0 => Ok(()), SOCKET_ERROR => Err(io::Error::last_os_error()), - _ => panic!("unexpected return value"), + _ => Ok(()), + } +} + +pub(crate) fn set_linger(socket: TcpSocket, dur: Option<Duration>) -> io::Result<()> { + let val: linger = linger { + l_onoff: if dur.is_some() { 1 } else { 0 }, + l_linger: dur.map(|dur| dur.as_secs() as c_ushort).unwrap_or_default(), + }; + + match unsafe { setsockopt( + socket, + SOL_SOCKET, + SO_LINGER, + &val as *const _ as *const c_char, + size_of::<linger>() as c_int, + ) } { + SOCKET_ERROR => Err(io::Error::last_os_error()), + _ => Ok(()), } } |