123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- //! poll implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/poll.h.html
- use core::{mem, slice};
- use crate::{
- fs::File,
- header::sys_epoll::{
- epoll_create1, epoll_ctl, epoll_data, epoll_event, epoll_wait, EPOLLERR, EPOLLHUP, EPOLLIN,
- EPOLLNVAL, EPOLLOUT, EPOLLPRI, EPOLLRDBAND, EPOLLRDNORM, EPOLLWRBAND, EPOLLWRNORM, EPOLL_CLOEXEC, EPOLL_CTL_ADD,
- },
- platform::types::*,
- };
- pub const POLLIN: c_short = 0x001;
- pub const POLLPRI: c_short = 0x002;
- pub const POLLOUT: c_short = 0x004;
- pub const POLLERR: c_short = 0x008;
- pub const POLLHUP: c_short = 0x010;
- pub const POLLNVAL: c_short = 0x020;
- pub const POLLRDNORM: c_short = 0x040;
- pub const POLLRDBAND: c_short = 0x080;
- pub const POLLWRNORM: c_short = 0x100;
- pub const POLLWRBAND: c_short = 0x200;
- pub type nfds_t = c_ulong;
- #[repr(C)]
- pub struct pollfd {
- pub fd: c_int,
- pub events: c_short,
- pub revents: c_short,
- }
- pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int {
- let event_map = [
- (POLLIN, EPOLLIN),
- (POLLPRI, EPOLLPRI),
- (POLLOUT, EPOLLOUT),
- (POLLERR, EPOLLERR),
- (POLLHUP, EPOLLHUP),
- (POLLNVAL, EPOLLNVAL),
- (POLLRDNORM, EPOLLRDNORM),
- (POLLWRNORM, EPOLLWRNORM),
- (POLLRDBAND, EPOLLRDBAND),
- (POLLWRBAND, EPOLLWRBAND),
- ];
- let ep = {
- let epfd = epoll_create1(EPOLL_CLOEXEC);
- if epfd < 0 {
- return -1;
- }
- File::new(epfd)
- };
- for i in 0..fds.len() {
- let mut pfd = &mut fds[i];
- let mut event = epoll_event {
- events: 0,
- data: epoll_data { u64: i as u64 },
- ..Default::default()
- };
- for (p, ep) in event_map.iter() {
- if pfd.events & p > 0 {
- event.events |= ep;
- }
- }
- pfd.revents = 0;
- if epoll_ctl(*ep, EPOLL_CTL_ADD, pfd.fd, &mut event) < 0 {
- return -1;
- }
- }
- let mut events: [epoll_event; 32] = unsafe { mem::zeroed() };
- let res = epoll_wait(*ep, events.as_mut_ptr(), events.len() as c_int, timeout);
- if res < 0 {
- return -1;
- }
- for event in events.iter().take(res as usize) {
- let pi = unsafe { event.data.u64 as usize };
- // TODO: Error status when fd does not match?
- if let Some(pfd) = fds.get_mut(pi) {
- for (p, ep) in event_map.iter() {
- if event.events & ep > 0 {
- pfd.revents |= p;
- }
- }
- }
- }
- let mut count = 0;
- for pfd in fds.iter() {
- if pfd.revents > 0 {
- count += 1;
- }
- }
- count
- }
- #[no_mangle]
- pub unsafe extern "C" fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int {
- trace_expr!(
- poll_epoll(slice::from_raw_parts_mut(fds, nfds as usize), timeout),
- "poll({:p}, {}, {})",
- fds,
- nfds,
- timeout
- )
- }
|