1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-26 01:43:29 +04:00

Fix sys_exit/sys_exit_group deadlock

This commit is contained in:
Jiajie Chen 2019-03-11 17:19:00 +08:00
parent 14a1046c57
commit 17c08ce26c
2 changed files with 24 additions and 12 deletions

View File

@ -365,13 +365,6 @@ impl Process {
} }
self.futexes.get(&uaddr).unwrap().clone() self.futexes.get(&uaddr).unwrap().clone()
} }
pub fn report_exit_to_parent(&mut self, exit_code: usize) {
if let Some(parent) = &self.parent {
let mut parent = parent.lock();
parent.child_exit_code.insert(self.pid.get(), exit_code);
parent.child_exit.notify_one();
}
}
} }

View File

@ -179,11 +179,21 @@ pub fn sys_exit(exit_code: usize) -> ! {
info!("exit: {}, code: {}", tid, exit_code); info!("exit: {}, code: {}", tid, exit_code);
let mut proc = process(); let mut proc = process();
proc.threads.retain(|&id| id != tid); proc.threads.retain(|&id| id != tid);
if proc.threads.len() == 0 {
// last thread // for last thread,
proc.report_exit_to_parent(exit_code); // notify parent and fill exit code
} // avoid deadlock
let exit = proc.threads.len() == 0;
let proc_parent = proc.parent.clone();
let pid = proc.pid.get();
drop(proc); drop(proc);
if exit {
if let Some(parent) = proc_parent {
let mut parent = parent.lock();
parent.child_exit_code.insert(pid, exit_code);
parent.child_exit.notify_one();
}
}
// perform futex wake 1 // perform futex wake 1
// ref: http://man7.org/linux/man-pages/man2/set_tid_address.2.html // ref: http://man7.org/linux/man-pages/man2/set_tid_address.2.html
@ -210,8 +220,17 @@ pub fn sys_exit_group(exit_code: usize) -> ! {
for tid in proc.threads.iter() { for tid in proc.threads.iter() {
processor().manager().exit(*tid, exit_code); processor().manager().exit(*tid, exit_code);
} }
proc.report_exit_to_parent(exit_code);
// notify parent and fill exit code
// avoid deadlock
let proc_parent = proc.parent.clone();
let pid = proc.pid.get();
drop(proc); drop(proc);
if let Some(parent) = proc_parent {
let mut parent = parent.lock();
parent.child_exit_code.insert(pid, exit_code);
parent.child_exit.notify_one();
}
processor().yield_now(); processor().yield_now();
unreachable!(); unreachable!();