Release Process resources via Weak reference
This commit is contained in:
parent
c31f5334d7
commit
37f724c656
@ -20,7 +20,8 @@ pub fn do_exit(exit_status: i32) {
|
||||
current.status = Status::ZOMBIE;
|
||||
|
||||
// Update children
|
||||
for child_ref in ¤t.children {
|
||||
for child_weak in ¤t.children {
|
||||
let child_ref = child_weak.upgrade().unwrap();
|
||||
let mut child = child_ref.lock().unwrap();
|
||||
child.parent = Some(IDLE_PROCESS.clone());
|
||||
}
|
||||
@ -58,12 +59,13 @@ pub fn do_exit(exit_status: i32) {
|
||||
pub fn do_wait4(child_filter: &ChildProcessFilter, exit_status: &mut i32)
|
||||
-> Result<pid_t, Error>
|
||||
{
|
||||
let waiter = {
|
||||
let current_ref = get_current();
|
||||
let waiter = {
|
||||
let mut current = current_ref.lock().unwrap();
|
||||
|
||||
let mut any_child_to_wait_for = false;
|
||||
for child_ref in current.get_children() {
|
||||
for child_weak in current.get_children() {
|
||||
let child_ref = child_weak.upgrade().unwrap();
|
||||
let child = child_ref.lock().unwrap();
|
||||
|
||||
let may_wait_for = match child_filter {
|
||||
@ -98,23 +100,27 @@ pub fn do_wait4(child_filter: &ChildProcessFilter, exit_status: &mut i32)
|
||||
};
|
||||
|
||||
let child_pid = Waiter::sleep_until_woken_with_result(waiter);
|
||||
if child_pid == 0 { panic!("THIS SHOULD NEVER HAPPEN!"); }
|
||||
|
||||
{
|
||||
let current_ref = get_current();
|
||||
let mut current = current_ref.lock().unwrap();
|
||||
current.waiting_children = None;
|
||||
}
|
||||
|
||||
let child_ref = process_table::get(child_pid).unwrap();
|
||||
let child = {
|
||||
let child_i = {
|
||||
let mut child_i_opt = None;
|
||||
for (child_i, child_weak) in current.children.iter().enumerate() {
|
||||
let child_ref = child_weak.upgrade().unwrap();
|
||||
let child = child_ref.lock().unwrap();
|
||||
if child.get_pid() != child_pid { continue; }
|
||||
|
||||
if child.get_status() != Status::ZOMBIE {
|
||||
panic!("THIS SHOULD NEVER HAPPEN!");
|
||||
}
|
||||
child
|
||||
};
|
||||
child_i_opt = Some(child_i);
|
||||
*exit_status = child.get_exit_status();
|
||||
}
|
||||
child_i_opt.unwrap()
|
||||
};
|
||||
current.children.swap_remove(child_i);
|
||||
current.waiting_children = None;
|
||||
|
||||
// Release the last reference to the child process
|
||||
process_table::remove(child_pid);
|
||||
|
||||
Ok(child_pid)
|
||||
|
@ -20,14 +20,14 @@ pub struct Process {
|
||||
exit_status: i32,
|
||||
exec_path: String,
|
||||
parent: Option<ProcessRef>,
|
||||
children: Vec<ProcessRef>,
|
||||
children: Vec<ProcessWeakRef>,
|
||||
waiting_children: Option<WaitQueue<ChildProcessFilter, pid_t>>,
|
||||
vm: ProcessVM,
|
||||
file_table: FileTable,
|
||||
}
|
||||
|
||||
pub type ProcessRef = Arc<SgxMutex<Process>>;
|
||||
|
||||
pub type ProcessWeakRef = std::sync::Weak<SgxMutex<Process>>;
|
||||
|
||||
pub fn do_getpid() -> pid_t {
|
||||
let current_ref = get_current();
|
||||
@ -58,7 +58,7 @@ mod spawn;
|
||||
mod wait;
|
||||
mod exit;
|
||||
|
||||
use prelude::*;
|
||||
use super::{*};
|
||||
use vm::{ProcessVM, VMRangeTrait};
|
||||
use fs::{FileTable, File, FileRef};
|
||||
use self::task::{Task};
|
||||
|
@ -58,7 +58,7 @@ impl Process {
|
||||
pub fn get_files(&self) -> &FileTable { &self.file_table }
|
||||
pub fn get_files_mut(&mut self) -> &mut FileTable { &mut self.file_table }
|
||||
pub fn get_parent(&self) -> &ProcessRef { self.parent.as_ref().unwrap() }
|
||||
pub fn get_children(&self) -> &[ProcessRef] { &self.children }
|
||||
pub fn get_children(&self) -> &[ProcessWeakRef] { &self.children }
|
||||
}
|
||||
|
||||
impl Drop for Process {
|
||||
|
@ -109,6 +109,6 @@ fn parent_adopts_new_child(parent_ref: &ProcessRef, child_ref: &ProcessRef)
|
||||
{
|
||||
let mut parent = parent_ref.lock().unwrap();
|
||||
let mut child = child_ref.lock().unwrap();
|
||||
parent.children.push(child_ref.clone());
|
||||
parent.children.push(Arc::downgrade(child_ref));
|
||||
child.parent = Some(parent_ref.clone());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user