From 17c08ce26c0f318d8da489009a8cdd6ecb8f8511 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Mon, 11 Mar 2019 17:19:00 +0800 Subject: [PATCH] Fix sys_exit/sys_exit_group deadlock --- kernel/src/process/structs.rs | 7 ------- kernel/src/syscall/proc.rs | 29 ++++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index dc26a6e..8cca5a1 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -365,13 +365,6 @@ impl Process { } 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(); - } - } } diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index eabc6a1..851f8fd 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -179,11 +179,21 @@ pub fn sys_exit(exit_code: usize) -> ! { info!("exit: {}, code: {}", tid, exit_code); let mut proc = process(); proc.threads.retain(|&id| id != tid); - if proc.threads.len() == 0 { - // last thread - proc.report_exit_to_parent(exit_code); - } + + // for last thread, + // 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); + 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 // 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() { 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); + 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(); unreachable!();