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;
|
current.status = Status::ZOMBIE;
|
||||||
|
|
||||||
// Update children
|
// 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();
|
let mut child = child_ref.lock().unwrap();
|
||||||
child.parent = Some(IDLE_PROCESS.clone());
|
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)
|
pub fn do_wait4(child_filter: &ChildProcessFilter, exit_status: &mut i32)
|
||||||
-> Result<pid_t, Error>
|
-> Result<pid_t, Error>
|
||||||
{
|
{
|
||||||
|
let current_ref = get_current();
|
||||||
let waiter = {
|
let waiter = {
|
||||||
let current_ref = get_current();
|
|
||||||
let mut current = current_ref.lock().unwrap();
|
let mut current = current_ref.lock().unwrap();
|
||||||
|
|
||||||
let mut any_child_to_wait_for = false;
|
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 child = child_ref.lock().unwrap();
|
||||||
|
|
||||||
let may_wait_for = match child_filter {
|
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);
|
let child_pid = Waiter::sleep_until_woken_with_result(waiter);
|
||||||
if child_pid == 0 { panic!("THIS SHOULD NEVER HAPPEN!"); }
|
|
||||||
|
|
||||||
{
|
let mut current = current_ref.lock().unwrap();
|
||||||
let current_ref = get_current();
|
let child_i = {
|
||||||
let mut current = current_ref.lock().unwrap();
|
let mut child_i_opt = None;
|
||||||
current.waiting_children = 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; }
|
||||||
|
|
||||||
let child_ref = process_table::get(child_pid).unwrap();
|
if child.get_status() != Status::ZOMBIE {
|
||||||
let child = {
|
panic!("THIS SHOULD NEVER HAPPEN!");
|
||||||
let child = child_ref.lock().unwrap();
|
}
|
||||||
if child.get_status() != Status::ZOMBIE {
|
child_i_opt = Some(child_i);
|
||||||
panic!("THIS SHOULD NEVER HAPPEN!");
|
*exit_status = child.get_exit_status();
|
||||||
}
|
}
|
||||||
child
|
child_i_opt.unwrap()
|
||||||
};
|
};
|
||||||
*exit_status = child.get_exit_status();
|
current.children.swap_remove(child_i);
|
||||||
|
current.waiting_children = None;
|
||||||
|
|
||||||
|
// Release the last reference to the child process
|
||||||
process_table::remove(child_pid);
|
process_table::remove(child_pid);
|
||||||
|
|
||||||
Ok(child_pid)
|
Ok(child_pid)
|
||||||
|
@ -20,14 +20,14 @@ pub struct Process {
|
|||||||
exit_status: i32,
|
exit_status: i32,
|
||||||
exec_path: String,
|
exec_path: String,
|
||||||
parent: Option<ProcessRef>,
|
parent: Option<ProcessRef>,
|
||||||
children: Vec<ProcessRef>,
|
children: Vec<ProcessWeakRef>,
|
||||||
waiting_children: Option<WaitQueue<ChildProcessFilter, pid_t>>,
|
waiting_children: Option<WaitQueue<ChildProcessFilter, pid_t>>,
|
||||||
vm: ProcessVM,
|
vm: ProcessVM,
|
||||||
file_table: FileTable,
|
file_table: FileTable,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ProcessRef = Arc<SgxMutex<Process>>;
|
pub type ProcessRef = Arc<SgxMutex<Process>>;
|
||||||
|
pub type ProcessWeakRef = std::sync::Weak<SgxMutex<Process>>;
|
||||||
|
|
||||||
pub fn do_getpid() -> pid_t {
|
pub fn do_getpid() -> pid_t {
|
||||||
let current_ref = get_current();
|
let current_ref = get_current();
|
||||||
@ -58,7 +58,7 @@ mod spawn;
|
|||||||
mod wait;
|
mod wait;
|
||||||
mod exit;
|
mod exit;
|
||||||
|
|
||||||
use prelude::*;
|
use super::{*};
|
||||||
use vm::{ProcessVM, VMRangeTrait};
|
use vm::{ProcessVM, VMRangeTrait};
|
||||||
use fs::{FileTable, File, FileRef};
|
use fs::{FileTable, File, FileRef};
|
||||||
use self::task::{Task};
|
use self::task::{Task};
|
||||||
|
@ -58,7 +58,7 @@ impl Process {
|
|||||||
pub fn get_files(&self) -> &FileTable { &self.file_table }
|
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_files_mut(&mut self) -> &mut FileTable { &mut self.file_table }
|
||||||
pub fn get_parent(&self) -> &ProcessRef { self.parent.as_ref().unwrap() }
|
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 {
|
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 parent = parent_ref.lock().unwrap();
|
||||||
let mut child = child_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());
|
child.parent = Some(parent_ref.clone());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user