Commit 89b4fa80 authored by Jeremy Soller's avatar Jeremy Soller

Merge branch 'jD91mZM2/epoll' into 'epoll'

Add completely untested redox epoll implementation

See merge request !211
parents 5715fb7b 4c8f51ac
Pipeline #4002 failed with stages
in 4 minutes and 36 seconds
......@@ -54,6 +54,7 @@ pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int {
data: epoll_data {
u64: i as u64,
},
..Default::default()
};
for (p, ep) in event_map.iter() {
......
use platform::types::*;
pub const EPOLL_CLOEXEC: c_int = 0x8_0000;
pub const EPOLLIN: c_uint = 0x001;
pub const EPOLLPRI: c_uint = 0x002;
pub const EPOLLOUT: c_uint = 0x004;
pub const EPOLLRDNORM: c_uint = 0x040;
pub const EPOLLNVAL: c_uint = 0x020;
pub const EPOLLRDBAND: c_uint = 0x080;
pub const EPOLLWRNORM: c_uint = 0x100;
pub const EPOLLWRBAND: c_uint = 0x200;
pub const EPOLLMSG: c_uint = 0x400;
pub const EPOLLERR: c_uint = 0x008;
pub const EPOLLHUP: c_uint = 0x010;
pub const EPOLLRDHUP: c_uint = 0x2000;
pub const EPOLLEXCLUSIVE: c_uint = 1 << 28;
pub const EPOLLWAKEUP: c_uint = 1 << 29;
pub const EPOLLONESHOT: c_uint = 1 << 30;
pub const EPOLLET: c_uint = 1 << 31;
......@@ -20,31 +20,32 @@ pub const EPOLL_CTL_ADD: c_int = 1;
pub const EPOLL_CTL_DEL: c_int = 2;
pub const EPOLL_CTL_MOD: c_int = 3;
pub const EPOLLIN: u32 = 0x0001;
pub const EPOLLPRI: u32 = 0x0002;
pub const EPOLLOUT: u32 = 0x0004;
pub const EPOLLERR: u32 = 0x0008;
pub const EPOLLHUP: u32 = 0x0010;
pub const EPOLLNVAL: u32 = 0x0020;
pub const EPOLLRDNORM: u32 = 0x0040;
pub const EPOLLRDBAND: u32 = 0x0080;
pub const EPOLLWRNORM: u32 = 0x0100;
pub const EPOLLWRBAND: u32 = 0x0200;
pub const EPOLLMSG: u32 = 0x0400;
pub const EPOLLRDHUP: u32 = 0x2000;
#[repr(C)]
#[derive(Clone, Copy)]
pub union epoll_data {
pub ptr: *mut c_void,
pub fd: c_int,
pub u32: u32,
pub u64: u64,
}
impl Default for epoll_data {
fn default() -> Self {
Self { u64: 0 }
}
}
#[repr(C)]
#[derive(Clone, Copy, Default)]
// This will match in size with syscall::Event (24 bytes on 64-bit
// systems) on redox. The `Default` trait is here so we don't need to
// worry about the padding when using this type.
pub struct epoll_event {
pub events: u32,
pub data: epoll_data,
pub events: u32, // 4 bytes
// 4 automatic alignment bytes
pub data: epoll_data, // 8 bytes
#[cfg(target_os = "redox")]
pub _pad: u64, // 8 bytes
}
#[no_mangle]
......
use syscall::flag::{EVENT_READ, EVENT_WRITE};
use header::fcntl::O_CLOEXEC;
use platform::types::*;
pub const EPOLL_CLOEXEC: c_int = 0x0100_0000;
pub const EPOLL_CLOEXEC: c_int = O_CLOEXEC;
pub const EPOLLIN: c_uint = EVENT_READ as c_uint;
pub const EPOLLPRI: c_uint = 0;
pub const EPOLLOUT: c_uint = EVENT_WRITE as c_uint;
pub const EPOLLRDNORM: c_uint = 0;
pub const EPOLLNVAL: c_uint = 0;
pub const EPOLLRDBAND: c_uint = 0;
pub const EPOLLWRNORM: c_uint = 0;
pub const EPOLLWRBAND: c_uint = 0;
pub const EPOLLMSG: c_uint = 0;
pub const EPOLLERR: c_uint = 0;
pub const EPOLLHUP: c_uint = 0;
pub const EPOLLRDHUP: c_uint = 0;
pub const EPOLLEXCLUSIVE: c_uint = 0;
pub const EPOLLWAKEUP: c_uint = 0;
pub const EPOLLONESHOT: c_uint = 0;
pub const EPOLLET: c_uint = 0;
......@@ -80,6 +80,7 @@ pub fn select_epoll(
data: epoll_data {
fd: fd,
},
..Default::default()
};
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
return -1;
......@@ -93,6 +94,7 @@ pub fn select_epoll(
data: epoll_data {
fd: fd,
},
..Default::default()
};
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
return -1;
......@@ -106,6 +108,7 @@ pub fn select_epoll(
data: epoll_data {
fd: fd,
},
..Default::default()
};
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
return -1;
......
use super::super::types::*;
use super::super::{Pal, PalEpoll};
use super::Sys;
use c_str::CStr;
use core::{mem, slice};
use fs::File;
use io::prelude::*;
use header::errno::*;
use header::fcntl::*;
use header::signal::sigset_t;
use header::sys_epoll::*;
use syscall::data::{Event, TimeSpec};
use syscall::flag::EVENT_READ;
impl PalEpoll for Sys {
fn epoll_create1(flags: c_int) -> c_int {
Sys::open(
CStr::from_bytes_with_nul(b"event:\0").unwrap(),
O_RDWR | flags,
0
)
}
fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int {
Sys::write(epfd, &Event {
id: fd as usize,
flags: unsafe { (*event).events as usize },
// NOTE: Danger when using non 64-bit systems. If this is
// needed, use a box or something
data: unsafe { mem::transmute((*event).data) }
}) as c_int
}
fn epoll_pwait(epfd: c_int, mut events: *mut epoll_event, maxevents: c_int, timeout: c_int, _sigset: *const sigset_t) -> c_int {
// TODO: sigset
let _timer;
if timeout != -1 {
_timer = File::open(CStr::from_bytes_with_nul(b"time:\0").unwrap(), O_RDWR);
match _timer {
Err(_) => return -1,
Ok(mut timer) => {
let mut time = TimeSpec::default();
if let Err(err) = timer.read(&mut time) {
return -1;
}
time.tv_nsec += timeout;
if let Err(err) = timer.write(&time) {
return -1;
}
if Sys::write(epfd, &Event {
id: timer.fd as usize,
flags: EVENT_READ,
data: 0
}) == -1 {
return -1;
}
}
}
}
let bytes_read = Sys::read(epfd, unsafe { slice::from_raw_parts_mut(
events as *mut u8,
maxevents as usize
) });
if bytes_read == -1 {
return -1;
}
let read = bytes_read as usize / mem::size_of::<Event>();
for i in 0..maxevents {
unsafe {
let event = *(events as *mut Event);
if event.data == 0 {
return EINTR;
}
*events = epoll_event {
events: event.flags as _,
data: mem::transmute(event.data),
..Default::default()
};
events = events.add(mem::size_of::<epoll_event>());
}
}
read as c_int
}
}
//! sys/socket implementation, following http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/socket.h.html
use cbitset::BitSet;
use core::result::Result as CoreResult;
use core::{mem, ptr, slice};
use syscall::data::Map;
......@@ -27,6 +26,7 @@ use io::{self, BufReader, SeekFrom};
use super::types::*;
use super::{errno, Pal, Read};
mod epoll;
mod extra;
mod signal;
mod socket;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment