diff options
Diffstat (limited to 'src/sys/windows')
-rw-r--r-- | src/sys/windows/afd.rs | 2 | ||||
-rw-r--r-- | src/sys/windows/io_status_block.rs | 2 | ||||
-rw-r--r-- | src/sys/windows/mod.rs | 6 | ||||
-rw-r--r-- | src/sys/windows/selector.rs | 26 | ||||
-rw-r--r-- | src/sys/windows/tcp.rs | 48 |
5 files changed, 70 insertions, 14 deletions
diff --git a/src/sys/windows/afd.rs b/src/sys/windows/afd.rs index 82c8e9e..b2e3b11 100644 --- a/src/sys/windows/afd.rs +++ b/src/sys/windows/afd.rs @@ -111,7 +111,7 @@ impl Afd { } } -cfg_net! { +cfg_io_source! { use miow::iocp::CompletionPort; use ntapi::ntioapi::FILE_OPEN; use ntapi::ntioapi::NtCreateFile; diff --git a/src/sys/windows/io_status_block.rs b/src/sys/windows/io_status_block.rs index db6729c..9da5e7a 100644 --- a/src/sys/windows/io_status_block.rs +++ b/src/sys/windows/io_status_block.rs @@ -4,7 +4,7 @@ use std::ops::{Deref, DerefMut}; pub struct IoStatusBlock(IO_STATUS_BLOCK); -cfg_net! { +cfg_io_source! { use ntapi::ntioapi::IO_STATUS_BLOCK_u; impl IoStatusBlock { diff --git a/src/sys/windows/mod.rs b/src/sys/windows/mod.rs index 7bba6dd..25590c2 100644 --- a/src/sys/windows/mod.rs +++ b/src/sys/windows/mod.rs @@ -42,6 +42,10 @@ mod waker; pub(crate) use waker::Waker; cfg_net! { + mod net; +} + +cfg_io_source! { use std::io; use std::os::windows::io::RawSocket; use std::pin::Pin; @@ -49,8 +53,6 @@ cfg_net! { use crate::{poll, Interest, Registry, Token}; - mod net; - struct InternalState { selector: Arc<SelectorInner>, token: Token, diff --git a/src/sys/windows/selector.rs b/src/sys/windows/selector.rs index 4a38300..df2c3f0 100644 --- a/src/sys/windows/selector.rs +++ b/src/sys/windows/selector.rs @@ -12,6 +12,7 @@ cfg_net! { use miow::iocp::{CompletionPort, CompletionStatus}; use std::collections::VecDeque; +use std::io; use std::marker::PhantomPinned; use std::os::windows::io::RawSocket; use std::pin::Pin; @@ -20,7 +21,6 @@ use std::sync::atomic::AtomicUsize; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Duration; -use std::io; use winapi::shared::ntdef::NT_SUCCESS; use winapi::shared::ntdef::{HANDLE, PVOID}; use winapi::shared::ntstatus::STATUS_CANCELLED; @@ -47,7 +47,7 @@ impl AfdGroup { } } -cfg_net! { +cfg_io_source! { const POLL_GROUP__MAX_GROUP_SIZE: usize = 32; impl AfdGroup { @@ -256,7 +256,7 @@ impl SockState { } } -cfg_net! { +cfg_io_source! { impl SockState { fn new(raw_socket: RawSocket, afd: Arc<Afd>) -> io::Result<SockState> { Ok(SockState { @@ -327,8 +327,9 @@ static NEXT_ID: AtomicUsize = AtomicUsize::new(0); pub struct Selector { #[cfg(debug_assertions)] id: usize, - pub(super) inner: Arc<SelectorInner>, + #[cfg(debug_assertions)] + has_waker: AtomicBool, } impl Selector { @@ -340,6 +341,8 @@ impl Selector { #[cfg(debug_assertions)] id, inner: Arc::new(inner), + #[cfg(debug_assertions)] + has_waker: AtomicBool::new(false), } }) } @@ -349,6 +352,8 @@ impl Selector { #[cfg(debug_assertions)] id: self.id, inner: Arc::clone(&self.inner), + #[cfg(debug_assertions)] + has_waker: AtomicBool::new(self.has_waker.load(Ordering::Acquire)), }) } @@ -360,6 +365,11 @@ impl Selector { self.inner.select(events, timeout) } + #[cfg(debug_assertions)] + pub fn register_waker(&self) -> bool { + self.has_waker.swap(true, Ordering::AcqRel) + } + pub(super) fn clone_port(&self) -> Arc<CompletionPort> { self.inner.cp.clone() } @@ -370,7 +380,7 @@ impl Selector { } } -cfg_net! { +cfg_io_source! { use super::InternalState; use crate::Token; @@ -499,7 +509,7 @@ impl SelectorInner { } else if iocp_event.token() % 2 == 1 { // Handle is a named pipe. This could be extended to be any non-AFD event. let callback = (*(iocp_event.overlapped() as *mut super::Overlapped)).callback; - + let len = events.len(); callback(iocp_event.entry(), Some(events)); n += events.len() - len; @@ -525,7 +535,7 @@ impl SelectorInner { } } -cfg_net! { +cfg_io_source! { use std::mem::size_of; use std::ptr::null_mut; use winapi::um::mswsock; @@ -701,7 +711,7 @@ impl Drop for SelectorInner { let callback = unsafe { (*(iocp_event.overlapped() as *mut super::Overlapped)).callback }; - + callback(iocp_event.entry(), None); } else { // drain sock state to release memory of Arc reference diff --git a/src/sys/windows/tcp.rs b/src/sys/windows/tcp.rs index 46ac1ac..b78d864 100644 --- a/src/sys/windows/tcp.rs +++ b/src/sys/windows/tcp.rs @@ -1,14 +1,17 @@ use std::io; use std::mem::size_of; -use std::net::{self, SocketAddr}; +use std::net::{self, SocketAddr, SocketAddrV4, SocketAddrV6}; 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::ws2def::{SOCKADDR_STORAGE, AF_INET, SOCKADDR_IN}; +use winapi::shared::ws2ipdef::SOCKADDR_IN6_LH; + use winapi::shared::minwindef::{BOOL, TRUE, FALSE}; use winapi::um::winsock2::{ - self, closesocket, linger, setsockopt, PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, + self, closesocket, linger, setsockopt, getsockopt, getsockname, PF_INET, PF_INET6, SOCKET, SOCKET_ERROR, SOCK_STREAM, SOL_SOCKET, SO_LINGER, SO_REUSEADDR, }; @@ -87,6 +90,47 @@ pub(crate) fn set_reuseaddr(socket: TcpSocket, reuseaddr: bool) -> io::Result<() } } +pub(crate) fn get_reuseaddr(socket: TcpSocket) -> io::Result<bool> { + let mut optval: c_char = 0; + let mut optlen = size_of::<BOOL>() as c_int; + + match unsafe { getsockopt( + socket, + SOL_SOCKET, + SO_REUSEADDR, + &mut optval as *mut _ as *mut _, + &mut optlen, + ) } { + SOCKET_ERROR => Err(io::Error::last_os_error()), + _ => Ok(optval != 0), + } +} + +pub(crate) fn get_localaddr(socket: TcpSocket) -> io::Result<SocketAddr> { + let mut addr: SOCKADDR_STORAGE = unsafe { std::mem::zeroed() }; + let mut length = std::mem::size_of_val(&addr) as c_int; + + match unsafe { getsockname( + socket, + &mut addr as *mut _ as *mut _, + &mut length + ) } { + SOCKET_ERROR => Err(io::Error::last_os_error()), + _ => { + let storage: *const SOCKADDR_STORAGE = (&addr) as *const _; + if addr.ss_family as c_int == AF_INET { + let sock_addr : SocketAddrV4 = unsafe { *(storage as *const SOCKADDR_IN as *const _) }; + Ok(sock_addr.into()) + } else { + let sock_addr : SocketAddrV6 = unsafe { *(storage as *const SOCKADDR_IN6_LH as *const _) }; + Ok(sock_addr.into()) + } + }, + } + + +} + 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 }, |