aboutsummaryrefslogtreecommitdiff
path: root/src/sys/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys/windows')
-rw-r--r--src/sys/windows/afd.rs2
-rw-r--r--src/sys/windows/io_status_block.rs2
-rw-r--r--src/sys/windows/mod.rs6
-rw-r--r--src/sys/windows/selector.rs26
-rw-r--r--src/sys/windows/tcp.rs48
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 },