mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-28 03:43:23 +00:00
86 lines
2.5 KiB
Rust
86 lines
2.5 KiB
Rust
use super::{
|
|
process_table,
|
|
signal::signals::{kernel::KernelSignal, user::UserSignal},
|
|
Pgid, Pid, Process,
|
|
};
|
|
use crate::prelude::*;
|
|
|
|
pub struct ProcessGroup {
|
|
inner: Mutex<ProcessGroupInner>,
|
|
}
|
|
|
|
struct ProcessGroupInner {
|
|
pgid: Pgid,
|
|
processes: BTreeMap<Pid, Arc<Process>>,
|
|
leader_process: Option<Arc<Process>>,
|
|
}
|
|
|
|
impl ProcessGroup {
|
|
fn default() -> Self {
|
|
ProcessGroup {
|
|
inner: Mutex::new(ProcessGroupInner {
|
|
pgid: 0,
|
|
processes: BTreeMap::new(),
|
|
leader_process: None,
|
|
}),
|
|
}
|
|
}
|
|
|
|
pub fn new(process: Arc<Process>) -> Self {
|
|
let process_group = ProcessGroup::default();
|
|
let pid = process.pid();
|
|
process_group.set_pgid(pid);
|
|
process_group.add_process(process.clone());
|
|
process_group.set_leader_process(process);
|
|
process_group
|
|
}
|
|
|
|
pub fn set_pgid(&self, pgid: Pgid) {
|
|
self.inner.lock().pgid = pgid;
|
|
}
|
|
|
|
pub fn set_leader_process(&self, leader_process: Arc<Process>) {
|
|
self.inner.lock().leader_process = Some(leader_process);
|
|
}
|
|
|
|
pub fn add_process(&self, process: Arc<Process>) {
|
|
self.inner.lock().processes.insert(process.pid(), process);
|
|
}
|
|
|
|
pub fn contains_process(&self, pid: Pid) -> bool {
|
|
self.inner.lock().processes.contains_key(&pid)
|
|
}
|
|
|
|
/// remove a process from this process group.
|
|
/// If this group contains no processes now, the group itself will be deleted from global table.
|
|
pub fn remove_process(&self, pid: Pid) {
|
|
let mut inner_lock = self.inner.lock();
|
|
inner_lock.processes.remove(&pid);
|
|
let len = inner_lock.processes.len();
|
|
let pgid = inner_lock.pgid;
|
|
// if self contains no process, remove self from table
|
|
if len == 0 {
|
|
// this must be the last statement
|
|
process_table::remove_process_group(pgid);
|
|
}
|
|
}
|
|
|
|
pub fn pgid(&self) -> Pgid {
|
|
self.inner.lock().pgid
|
|
}
|
|
|
|
/// send kernel signal to all processes in the group
|
|
pub fn kernel_signal(&self, signal: KernelSignal) {
|
|
for (_, process) in &self.inner.lock().processes {
|
|
process.enqueue_signal(Box::new(signal.clone()));
|
|
}
|
|
}
|
|
|
|
/// send user signal to all processes in the group
|
|
pub fn user_signal(&self, signal: UserSignal) {
|
|
for (_, process) in &self.inner.lock().processes {
|
|
process.enqueue_signal(Box::new(signal.clone()));
|
|
}
|
|
}
|
|
}
|