blob: 98b6fc63ec936a087a14a1d39d47fa815088f6a4 [file] [log] [blame]
mod afd;
mod io_status_block;
pub mod event;
pub use event::{Event, Events};
mod selector;
pub use selector::{Selector, SelectorInner, SockState};
mod overlapped;
use overlapped::Overlapped;
// Macros must be defined before the modules that use them
cfg_net! {
/// Helper macro to execute a system call that returns an `io::Result`.
//
// Macro must be defined before any modules that uses them.
macro_rules! syscall {
($fn: ident ( $($arg: expr),* $(,)* ), $err_test: path, $err_value: expr) => {{
let res = unsafe { $fn($($arg, )*) };
if $err_test(&res, &$err_value) {
Err(io::Error::last_os_error())
} else {
Ok(res)
}
}};
}
mod net;
pub(crate) mod tcp;
pub(crate) mod udp;
}
cfg_os_ext! {
pub(crate) mod named_pipe;
}
mod waker;
pub(crate) use waker::Waker;
cfg_io_source! {
use std::io;
use std::os::windows::io::RawSocket;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use crate::{poll, Interest, Registry, Token};
struct InternalState {
selector: Arc<SelectorInner>,
token: Token,
interests: Interest,
sock_state: Pin<Arc<Mutex<SockState>>>,
}
impl Drop for InternalState {
fn drop(&mut self) {
let mut sock_state = self.sock_state.lock().unwrap();
sock_state.mark_delete();
}
}
pub struct IoSourceState {
// This is `None` if the socket has not yet been registered.
//
// We box the internal state to not increase the size on the stack as the
// type might move around a lot.
inner: Option<Box<InternalState>>,
}
impl IoSourceState {
pub fn new() -> IoSourceState {
IoSourceState { inner: None }
}
pub fn do_io<T, F, R>(&self, f: F, io: &T) -> io::Result<R>
where
F: FnOnce(&T) -> io::Result<R>,
{
let result = f(io);
if let Err(ref e) = result {
if e.kind() == io::ErrorKind::WouldBlock {
self.inner.as_ref().map_or(Ok(()), |state| {
state
.selector
.reregister(state.sock_state.clone(), state.token, state.interests)
})?;
}
}
result
}
pub fn register(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
socket: RawSocket,
) -> io::Result<()> {
if self.inner.is_some() {
Err(io::ErrorKind::AlreadyExists.into())
} else {
poll::selector(registry)
.register(socket, token, interests)
.map(|state| {
self.inner = Some(Box::new(state));
})
}
}
pub fn reregister(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
match self.inner.as_mut() {
Some(state) => {
poll::selector(registry)
.reregister(state.sock_state.clone(), token, interests)
.map(|()| {
state.token = token;
state.interests = interests;
})
}
None => Err(io::ErrorKind::NotFound.into()),
}
}
pub fn deregister(&mut self) -> io::Result<()> {
match self.inner.as_mut() {
Some(state) => {
{
let mut sock_state = state.sock_state.lock().unwrap();
sock_state.mark_delete();
}
self.inner = None;
Ok(())
}
None => Err(io::ErrorKind::NotFound.into()),
}
}
}
}