#[cfg(unix)]
use std::os::unix::io::AsRawFd;
use std::convert::TryInto;
#[cfg(windows)]
use std::os::windows::io::AsRawSocket;
mod platform {
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
#[cfg(test)]
mod tests;
pub const EV_POLLIN: i16 = 1 << 0;
pub const EV_POLLOUT: i16 = 1 << 1;
#[cfg(unix)]
pub fn poll<A: AsRawFd>(socket: &A, event: i16) -> bool {
poll_timeout(socket, event, -1)
}
#[cfg(unix)]
pub fn poll_timeout<A: AsRawFd>(socket: &A, event: i16, timeout: i32) -> bool {
let mut fd = socket.as_raw_fd();
let fd_ptr = &mut fd as *mut i32;
unsafe {
let translated_events = translate_event(event);
return platform::c_poll(fd_ptr, 1, translated_events, timeout) == 0;
}
}
#[cfg(unix)]
pub fn poll_set(fds: &mut [i32], event: i16) -> i32 {
poll_set_timeout(fds, event, -1).unwrap()
}
#[cfg(unix)]
pub fn poll_set_timeout(fds: &mut [i32], event: i16, timeout: i32) -> Option<i32> {
unsafe {
let translated_events = translate_event(event);
let res = platform::c_poll(
fds.as_mut_ptr(),
fds.len().try_into().unwrap(),
translated_events,
timeout,
);
if res == -1 {
return None;
}
return Some(res);
}
}
#[cfg(unix)]
pub fn poll_set_ev(fds: &mut [i32], events: &mut [i16]) -> i32 {
poll_set_ev_timeout(fds, events, -1).unwrap()
}
#[cfg(unix)]
pub fn poll_set_ev_timeout(fds: &mut [i32], events: &mut [i16], timeout: i32) -> Option<i32> {
unsafe {
let mut translated = Vec::new();
for e in events {
translated.push(translate_event(*e));
}
let res = platform::c_poll_ev(
fds.as_mut_ptr(),
translated.as_mut_ptr(),
fds.len().try_into().unwrap(),
timeout,
);
if res == -1 {
return None;
}
return Some(res);
}
}
#[cfg(unix)]
pub fn get_fd_array<A: AsRawFd>(sockets: &[A]) -> Vec<i32> {
let mut res = Vec::new();
for socket in sockets {
res.push(socket.as_raw_fd());
}
res
}
#[cfg(windows)]
pub fn poll<A: AsRawSocket>(socket: &A, event: i16) -> bool {
poll_timeout(socket, event, -1)
}
#[cfg(windows)]
pub fn poll_timeout<A: AsRawSocket>(socket: &A, event: i16, timeout: i32) -> bool {
let mut fd = socket.as_raw_socket();
let fd_ptr = &mut fd as *mut u64;
unsafe {
let translated_events = translate_event(event);
return platform::c_poll(fd_ptr, 1, translated_events, timeout) == 0;
}
}
#[cfg(windows)]
pub fn poll_set_timeout(fds: &mut [u64], event: i16, timeout: i32) -> Option<i32> {
unsafe {
let translated_events = translate_event(event);
let res = platform::c_poll(
fds.as_mut_ptr(),
fds.len().try_into().unwrap(),
translated_events,
timeout,
);
if res == -1 {
return None;
}
return Some(res);
}
}
#[cfg(windows)]
pub fn poll_set(fds: &mut [u64], event: i16) -> i32 {
poll_set_timeout(fds, event, -1).unwrap()
}
#[cfg(windows)]
pub fn poll_set_ev_timeout(fds: &mut [u64], events: &mut [i16], timeout: i32) -> Option<i32> {
unsafe {
let mut translated = Vec::new();
for e in events {
translated.push(translate_event(*e));
}
let res = platform::c_poll_ev(
fds.as_mut_ptr(),
translated.as_mut_ptr(),
fds.len().try_into().unwrap(),
timeout,
);
if res == -1 {
return None;
}
return Some(res);
}
}
#[cfg(windows)]
pub fn poll_set_ev(fds: &mut [u64], events: &mut [i16]) -> i32 {
poll_set_ev_timeout(fds, events, -1).unwrap()
}
#[cfg(windows)]
pub fn get_fd_array<A: AsRawSocket>(sockets: &[A]) -> Vec<u64> {
let mut res = Vec::new();
for socket in sockets {
res.push(socket.as_raw_socket());
}
res
}
unsafe fn translate_event(ev: i16) -> i16 {
let mut translated = 0;
if (ev & EV_POLLIN) != 0 {
translated |= platform::ev_pollin;
}
if (ev & EV_POLLOUT) != 0 {
translated |= platform::ev_pollout;
}
translated
}