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