diff options
Diffstat (limited to 'src/sys/windows')
-rw-r--r-- | src/sys/windows/selector.rs | 43 | ||||
-rw-r--r-- | src/sys/windows/tcp.rs | 34 |
2 files changed, 45 insertions, 32 deletions
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(()), } } |