starry_process/
session.rs1use alloc::{
2 sync::{Arc, Weak},
3 vec::Vec,
4};
5use core::{any::Any, convert::Infallible, fmt};
6
7use ax_kspin::SpinNoIrq;
8use weak_map::WeakMap;
9
10use crate::{Pid, ProcessGroup};
11
12pub struct Session {
14 sid: Pid,
15 pub(crate) process_groups: SpinNoIrq<WeakMap<Pid, Weak<ProcessGroup>>>,
16 terminal: SpinNoIrq<Option<Arc<dyn Any + Send + Sync>>>,
17}
18
19impl Session {
20 pub(crate) fn new(sid: Pid) -> Arc<Self> {
22 Arc::new(Self {
23 sid,
24 process_groups: SpinNoIrq::new(WeakMap::new()),
25 terminal: SpinNoIrq::new(None),
26 })
27 }
28}
29
30impl Session {
31 pub fn sid(&self) -> Pid {
33 self.sid
34 }
35
36 pub fn process_groups(&self) -> Vec<Arc<ProcessGroup>> {
38 self.process_groups.lock().values().collect()
39 }
40
41 pub fn set_terminal_with(&self, terminal: impl FnOnce() -> Arc<dyn Any + Send + Sync>) -> bool {
43 self.try_set_terminal_with(|| Ok::<_, Infallible>(terminal()))
44 .unwrap()
45 }
46
47 pub fn try_set_terminal_with<E>(
49 &self,
50 terminal: impl FnOnce() -> Result<Arc<dyn Any + Send + Sync>, E>,
51 ) -> Result<bool, E> {
52 let mut guard = self.terminal.lock();
53 if guard.is_some() {
54 return Ok(false);
55 }
56 *guard = Some(terminal()?);
57 Ok(true)
58 }
59
60 pub fn unset_terminal(&self, term: &Arc<dyn Any + Send + Sync>) -> bool {
62 let mut guard = self.terminal.lock();
63 if guard.as_ref().is_some_and(|it| Arc::ptr_eq(it, term)) {
64 *guard = None;
65 true
66 } else {
67 false
68 }
69 }
70
71 pub fn terminal(&self) -> Option<Arc<dyn Any + Send + Sync>> {
73 self.terminal.lock().clone()
74 }
75}
76
77impl fmt::Debug for Session {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 write!(f, "Session({})", self.sid)
80 }
81}