Fix a potential racing in park() and unpark(), fix sys_poll for a running telnet

master
Jiajie Chen 6 years ago
parent 9e6483f488
commit 8b9aecca1c

@ -131,14 +131,14 @@ impl ThreadPool {
/// Insert/Remove it to/from scheduler if necessary.
fn set_status(&self, tid: Tid, status: Status) {
let mut proc_lock = self.threads[tid].lock();
let mut proc = proc_lock.as_mut().expect("process not exist");
if let Some(mut proc) = proc_lock.as_mut() {
trace!("process {} {:?} -> {:?}", tid, proc.status, status);
match (&proc.status, &status) {
(Status::Ready, Status::Ready) => return,
(Status::Ready, _) => panic!("can not remove a process from ready queue"),
(Status::Exited(_), _) => panic!("can not set status for a exited process"),
(Status::Sleeping, Status::Exited(_)) => self.timer.lock().stop(Event::Wakeup(tid)),
(Status::Running(_), Status::Ready) => {} // to stop a thread, use stop() intead
(Status::Running(_), Status::Ready) => {} // process will be added to scheduler in stop()
(_, Status::Ready) => self.scheduler.push(tid),
_ => {}
}
@ -151,6 +151,7 @@ impl ThreadPool {
_ => {}
}
}
}
pub fn get_status(&self, tid: Tid) -> Option<Status> {
self.threads[tid].lock().as_ref().map(|p| p.status.clone())

@ -72,7 +72,8 @@ pub fn backtrace() {
// Kernel stack at 0x0000_57ac_0000_0000 (defined in bootloader crate)
// size = 512 pages
current_fp = *(current_fp as *const usize).offset(0);
if current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::<usize>() {
if current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::<usize>() &&
current_fp <= 0xffff_ff00_0000_0000 {
break;
}
current_pc = *(current_fp as *const usize).offset(1);

@ -62,13 +62,15 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
loop {
use PollEvents as PE;
let mut proc = process();
let mut events = 0;
for poll in polls.iter_mut() {
poll.revents = PE::NONE;
match proc.files.get(&(poll.fd as usize)) {
Some(FileLike::File(_)) => {
// FIXME: assume it is stdin for now
if poll.events.contains(PE::IN) && STDIN.can_read() {
poll.revents = PE::IN;
return Ok(0);
poll.revents = poll.revents | PE::IN;
events = events + 1;
}
},
Some(FileLike::Socket(wrapper)) => {
@ -78,29 +80,42 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
let mut socket = sockets.get::<TcpSocket>(wrapper.handle);
if !socket.is_open() {
poll.revents = PE::HUP;
return Ok(0);
} else if socket.can_recv() && poll.events.contains(PE::IN) {
poll.revents = PE::IN;
return Ok(0);
} else if socket.can_send() && poll.events.contains(PE::OUT) {
poll.revents = PE::OUT;
return Ok(0);
poll.revents = poll.revents | PE::HUP;
events = events + 1;
} else {
if socket.can_recv() && poll.events.contains(PE::IN) {
poll.revents = poll.revents | PE::IN;
events = events + 1;
}
if socket.can_send() && poll.events.contains(PE::OUT) {
poll.revents = poll.revents | PE::OUT;
events = events + 1;
}
}
} else {
unimplemented!()
}
}
None => {
poll.revents = PE::ERR;
return Ok(0);
poll.revents = poll.revents | PE::ERR;
events = events + 1;
}
}
}
drop(proc);
if events > 0 {
return Ok(events as isize);
}
let current_time_ms = unsafe {crate::trap::TICK / crate::consts::USEC_PER_TICK / 1000};
if timeout_msecs < (1 << 31) && current_time_ms - begin_time_ms > timeout_msecs {
return Ok(0);
}
Condvar::wait_any(&[&STDIN.pushed, &(*SOCKET_ACTIVITY)]);
}
Ok(nfds as isize)
}
pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResult {
@ -704,6 +719,8 @@ pub struct PollFd {
bitflags! {
pub struct PollEvents: u16 {
/// Nothing Happens
const NONE = 0x0000;
/// There is data to read.
const IN = 0x0001;
/// Writing is now possible.

@ -294,6 +294,7 @@ pub fn sys_read_socket(proc: &mut Process, fd: usize, base: *mut u8, len: usize)
// avoid deadlock
drop(socket);
drop(sockets);
SOCKET_ACTIVITY._wait()
}
} else if let SocketType::Udp = wrapper.socket_type {

Loading…
Cancel
Save