rust_asio 0.3.2

Asynchronous I/O library
Documentation
use std::io;
use std::mem;
use std::cmp;
use std::hash;
use std::slice;
use std::boxed::FnBox;
pub use std::os::unix::io::{RawFd, AsRawFd};
pub use libc::{c_void, c_int, c_char, memcmp};
use {IoObject, IoService, SockAddr};

macro_rules! libc_try {
    ($expr:expr) => (match unsafe { $expr } {
        rc if rc >= 0 => rc,
        _ => return Err(::std::io::Error::last_os_error()),
    })
}

extern {
    #[cfg_attr(target_os = "linux", link_name = "__errno_location")]
    fn errno_location() -> *mut c_int;
}

fn errno() -> i32 {
    unsafe { *errno_location() }
}

mod unix;
pub use self::unix::*;

#[derive(Clone, Copy)]
pub struct ErrorCode(pub i32);
const READY: i32 = 0;

pub type Handler = Box<FnBox(*const IoService, ErrorCode) + Send + 'static>;

#[cfg(all(not(feature = "asio_no_epoll_reactor"), target_os = "linux"))]
pub mod epoll_reactor;

#[cfg(all(not(feature = "asio_no_epoll_reactor"), target_os = "linux"))]
pub use self::epoll_reactor::{
    EpollReactor as Reactor,
    EpollIoActor as IoActor,
    EpollIntrActor as IntrActor,
};

pub trait AsIoActor : IoObject + AsRawFd + 'static {
    fn as_io_actor(&self) -> &IoActor;
}

pub mod timer_queue;
pub use self::timer_queue::{Expiry, ToExpiry, TimerQueue, WaitActor};

pub trait AsWaitActor : IoObject + 'static {
    fn as_wait_actor(&self) -> &WaitActor;
}

#[cfg(target_os = "linux")]
pub mod timerfd_control;

#[cfg(target_os = "linux")]
pub use self::timerfd_control::Control;

pub mod ops;

#[cfg(all(not(feature = "asio_no_signal_set"), target_os = "linux"))]
pub mod signalfd;

fn eof() -> io::Error {
    io::Error::new(io::ErrorKind::UnexpectedEof, "End of File")
}

fn write_zero() -> io::Error {
    io::Error::new(io::ErrorKind::WriteZero, "Write Zero")
}

fn stopped() -> io::Error {
    io::Error::new(io::ErrorKind::Other, "Stopped")
}

fn canceled() -> io::Error {
    io::Error::from_raw_os_error(CANCELED)
}

pub fn sockaddr_eq<E: SockAddr>(lhs: &E, rhs: &E) -> bool {
    lhs.size() == rhs.size() && unsafe { memcmp(
        mem::transmute(lhs.as_sockaddr()),
        mem::transmute(rhs.as_sockaddr()),
        lhs.size())
    } == 0
}

pub fn sockaddr_cmp<E: SockAddr>(lhs: &E, rhs: &E) -> cmp::Ordering {
    let cmp = unsafe {
        memcmp(
            mem::transmute(lhs.as_sockaddr()),
            mem::transmute(rhs.as_sockaddr()),
            cmp::min(lhs.size(), rhs.size())
        )
    };
    if cmp == 0 {
        if lhs.size() < rhs.size() {
            cmp::Ordering::Less
        } else if lhs.size() > rhs.size() {
            cmp::Ordering::Greater
        } else {
            cmp::Ordering::Equal
        }
    } else if cmp < 0 {
        cmp::Ordering::Less
    } else {
        cmp::Ordering::Greater
    }
}

pub fn sockaddr_hash<E: SockAddr, H: hash::Hasher>(ep: &E, state: &mut H) {
    let ptr = ep.as_sockaddr() as *const _ as *const u8;
    let buf = unsafe { slice::from_raw_parts(ptr, ep.size()) };
    state.write(buf);
}