Skip to content

Commit

Permalink
Allow registration of custom handles on Windows
Browse files Browse the repository at this point in the history
This
  • Loading branch information
alexcrichton committed Dec 10, 2016
1 parent 6d13bbe commit cdef4f8
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 139 deletions.
61 changes: 61 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,67 @@ pub mod unix {
};
}

/// Windows-only extensions to the mio crate.
///
/// Mio on windows is currently implemented with IOCP for a high-performance
/// implementation of asynchronous I/O. Mio then provides TCP and UDP as sample
/// bindings for the system to connect networking types to asynchronous I/O. On
/// Unix this scheme is then also extensible to all other file descriptors with
/// the `EventedFd` type, but on Windows no such analog is available. The
/// purpose of this module, however, is to similarly provide a mechanism for
/// foreign I/O types to get hooked up into the IOCP event loop.
///
/// This module provides two types for interfacing with a custom IOCP handle:
///
/// * `Registration` - this type is intended to govern registration with mio's
/// `Poll` type. Each I/O object should contain an instance of `Registration`
/// that's interfaced with for the implementation of the `Evented` trait. The
/// `register`, `reregister`, and `deregister` methods for the `Evented` trait
/// all have rough analogs with `Registration`.
///
/// Note that this type **does not handle readiness**. That is, this type does
/// not handle whether sockets are readable/writable/etc. It's intended that
/// IOCP types will internally manage this state with a `SetReadiness` type
/// from the `poll` module. The `SetReadiness` is typically lazily created on
/// the first time that `Evented::register` is called and then stored in the
/// I/O object.
///
/// Also note that for types which represent streams of bytes the mio
/// interface of *readiness* doesn't map directly to the Windows model of
/// *completion*. This means that types will have to perform internal
/// buffering to ensure that a readiness interface can be provided. For a
/// sample implementation see the TCP/UDP modules in mio itself.
///
/// * `Overlapped` - this type is intended to be used as the concreate instances
/// of the `OVERLAPPED` type that most win32 methods expect. It's crucial, for
/// safety, that all asynchronous operations are initiated with an instance of
/// `Overlapped` and not another instantiation of `OVERLAPPED`.
///
/// Mio's `Overlapped` type is created with a function pointer that receives a
/// `CompletionStatus` type when called. This `CompletionStatus` type is
/// defined in the `miow` crate. Whenever a completion is posted to an IOCP
/// object the `OVERLAPPED` that was signaled will be interpreted as
/// `Overlapped` in the mio crate and this function pointer will be invoked.
/// Through this function pointer, and through the `OVERLAPPED` pointer,
/// implementations can handle management of I/O events.
///
/// The `Overlapped` internally contains another `Overlapped` type defined in
/// the `miow` crate which provides low-level access to Windows I/O APIs. This
/// type provides the ability to configure the various fields of the
/// underlying `OVERLAPPED` if necessary.
///
/// When put together these two types enable custom Windows handles to be
/// registered with mio's event loops. The `Registration` type is used to
/// associate handles and the `Overlapped` type is used to execute I/O
/// operations. When the I/O operations are completed a custom function pointer
/// is called which typically modifies a `SetReadiness` set by `Evented` methods
/// which will get later hooked into the mio event loop.
#[cfg(windows)]
pub mod windows {

pub use sys::{Overlapped, Registration};
}

// Conversion utilities
mod convert {
use std::time::Duration;
Expand Down
2 changes: 2 additions & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub use self::windows::{
TcpStream,
TcpListener,
UdpSocket,
Overlapped,
Registration,
};

#[cfg(windows)]
Expand Down
6 changes: 2 additions & 4 deletions src/sys/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ use std::os::windows::prelude::*;
use kernel32;
use winapi;

use self::selector::Overlapped;

mod awakener;
#[macro_use]
mod selector;
Expand All @@ -153,7 +151,7 @@ mod from_raw_arc;
mod buffer_pool;

pub use self::awakener::Awakener;
pub use self::selector::{Events, Selector};
pub use self::selector::{Events, Selector, Overlapped, Registration};
pub use self::tcp::{TcpStream, TcpListener};
pub use self::udp::UdpSocket;

Expand All @@ -169,7 +167,7 @@ fn wouldblock() -> io::Error {
unsafe fn cancel(socket: &AsRawSocket,
overlapped: &Overlapped) -> io::Result<()> {
let handle = socket.as_raw_socket() as winapi::HANDLE;
let overlapped = overlapped.get_mut().raw();
let overlapped = (*overlapped.as_mut_ptr()).raw();
let ret = kernel32::CancelIoEx(handle, overlapped);
if ret == 0 {
Err(io::Error::last_os_error())
Expand Down
Loading

0 comments on commit cdef4f8

Please sign in to comment.