constellation/
process_manager.rs1use std::process::Child;
6
7use crossbeam_channel::{Receiver, Select};
8use log::{debug, warn};
9use profile_traits::mem::{ProfilerChan, ProfilerMsg};
10
11pub enum Process {
12 Unsandboxed(Child),
13 Sandboxed(u32),
14}
15
16impl Process {
17 fn pid(&self) -> u32 {
18 match self {
19 Self::Unsandboxed(child) => child.id(),
20 Self::Sandboxed(pid) => *pid,
21 }
22 }
23
24 fn wait(&mut self) {
25 match self {
26 Self::Unsandboxed(child) => {
27 let _ = child.wait();
28 },
29 Self::Sandboxed(_pid) => {
30 warn!("wait() is not yet implemented for sandboxed processes.");
32 },
33 }
34 }
35}
36
37type ProcessReceiver = Receiver<Result<(), ipc_channel::Error>>;
38
39pub(crate) struct ProcessManager {
40 processes: Vec<(Process, ProcessReceiver)>,
41 mem_profiler_chan: ProfilerChan,
42}
43
44impl ProcessManager {
45 pub fn new(mem_profiler_chan: ProfilerChan) -> Self {
46 Self {
47 processes: vec![],
48 mem_profiler_chan,
49 }
50 }
51
52 pub fn add(&mut self, receiver: ProcessReceiver, process: Process) {
53 debug!("Adding process pid={}", process.pid());
54 self.processes.push((process, receiver));
55 }
56
57 pub fn register<'a>(&'a self, select: &mut Select<'a>) {
58 for (_, receiver) in &self.processes {
59 select.recv(receiver);
60 }
61 }
62
63 pub fn receiver_at(&self, index: usize) -> &ProcessReceiver {
64 let (_, receiver) = &self.processes[index];
65 receiver
66 }
67
68 pub fn remove(&mut self, index: usize) {
69 let (mut process, _) = self.processes.swap_remove(index);
70 debug!("Removing process pid={}", process.pid());
71 self.mem_profiler_chan
73 .send(ProfilerMsg::UnregisterReporter(format!(
74 "system-content-{}",
75 process.pid()
76 )));
77 process.wait();
78 }
79}