minor improvement of sys_poll

toolchain_update
WangRunji 6 years ago
parent 42b02453a0
commit 1f2625e565

@ -45,43 +45,29 @@ pub fn sys_write_file(proc: &mut Process, fd: usize, base: *const u8, len: usize
Ok(len as isize) Ok(len as isize)
} }
#[repr(C)]
pub struct PollFd {
fd: u32,
events: u16,
revents: u16
}
const POLLIN: u16 = 0x0001;
const POLPRI: u16 = 0x0002;
const POLLOUT: u16 = 0x0004;
const POLLERR: u16 = 0x0008;
const POLLHUP: u16 = 0x0010;
const POLLNVAL: u16 = 0x0020;
pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult { pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult {
info!("poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", ufds, nfds, timeout_msecs); info!("poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", ufds, nfds, timeout_msecs);
let mut proc = process(); let mut proc = process();
proc.memory_set.check_mut_array(ufds, nfds)?; proc.memory_set.check_mut_array(ufds, nfds)?;
let slice = unsafe { slice::from_raw_parts_mut(ufds, nfds) }; let polls = unsafe { slice::from_raw_parts_mut(ufds, nfds) };
for i in 0..nfds { for poll in polls.iter() {
if proc.files.get(&(slice[i].fd as usize)).is_none() { if proc.files.get(&(poll.fd as usize)).is_none() {
return Err(SysError::EINVAL); return Err(SysError::EINVAL);
} }
} }
drop(proc); drop(proc);
let begin_time_ms = unsafe {crate::trap::TICK / crate::consts::USEC_PER_TICK / 1000}; let begin_time_ms = unsafe {crate::trap::TICK / crate::consts::USEC_PER_TICK / 1000};
loop { loop {
use PollEvents as PE;
let mut proc = process(); let mut proc = process();
for i in 0..nfds { for poll in polls.iter_mut() {
match proc.files.get(&(slice[i].fd as usize)) { match proc.files.get(&(poll.fd as usize)) {
Some(FileLike::File(_)) => { Some(FileLike::File(_)) => {
// assume it is stdin for now // FIXME: assume it is stdin for now
if (slice[i].events & POLLIN) != 0 && STDIN.can_read() { if poll.events.contains(PE::IN) && STDIN.can_read() {
slice[i].revents = POLLIN; poll.revents = PE::IN;
return Ok(0); return Ok(0);
} }
}, },
@ -92,13 +78,13 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
let mut socket = sockets.get::<TcpSocket>(wrapper.handle); let mut socket = sockets.get::<TcpSocket>(wrapper.handle);
if !socket.is_open() { if !socket.is_open() {
slice[i].revents = POLLHUP; poll.revents = PE::HUP;
return Ok(0); return Ok(0);
} else if socket.can_recv() && (slice[i].events & POLLIN) != 0 { } else if socket.can_recv() && poll.events.contains(PE::IN) {
slice[i].revents = POLLIN; poll.revents = PE::IN;
return Ok(0); return Ok(0);
} else if socket.can_send() && (slice[i].events & POLLOUT) != 0 { } else if socket.can_send() && poll.events.contains(PE::OUT) {
slice[i].revents = POLLIN; poll.revents = PE::OUT;
return Ok(0); return Ok(0);
} }
} else { } else {
@ -106,14 +92,14 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
} }
} }
None => { None => {
slice[i].revents = POLLERR; poll.revents = PE::ERR;
return Ok(0); return Ok(0);
} }
} }
} }
drop(proc);
Condvar::wait_any(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)]); Condvar::wait_any(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)]);
} }
Ok(nfds as isize) Ok(nfds as isize)
} }
@ -708,3 +694,25 @@ impl IoVecs {
buf buf
} }
} }
#[repr(C)]
pub struct PollFd {
fd: u32,
events: PollEvents,
revents: PollEvents,
}
bitflags! {
pub struct PollEvents: u16 {
/// There is data to read.
const IN = 0x0001;
/// Writing is now possible.
const OUT = 0x0004;
/// Error condition (return only)
const ERR = 0x0008;
/// Hang up (return only)
const HUP = 0x0010;
/// Invalid request: fd not open (return only)
const INVAL = 0x0020;
}
}

Loading…
Cancel
Save