starry_process/
session.rs

1use alloc::{
2    sync::{Arc, Weak},
3    vec::Vec,
4};
5use core::{any::Any, fmt};
6
7use kspin::SpinNoIrq;
8use weak_map::WeakMap;
9
10use crate::{Pid, ProcessGroup};
11
12/// A [`Session`] is a collection of [`ProcessGroup`]s.
13pub 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    /// Create a new [`Session`].
21    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    /// The [`Session`] ID.
32    pub fn sid(&self) -> Pid {
33        self.sid
34    }
35
36    /// The [`ProcessGroup`]s that belong to this [`Session`].
37    pub fn process_groups(&self) -> Vec<Arc<ProcessGroup>> {
38        self.process_groups.lock().values().collect()
39    }
40
41    /// Sets the terminal for this session.
42    pub fn set_terminal_with(&self, terminal: impl FnOnce() -> Arc<dyn Any + Send + Sync>) -> bool {
43        let mut guard = self.terminal.lock();
44        if guard.is_some() {
45            return false;
46        }
47        *guard = Some(terminal());
48        true
49    }
50
51    /// Unsets the terminal for this session if it is the given terminal.
52    pub fn unset_terminal(&self, term: &Arc<dyn Any + Send + Sync>) -> bool {
53        let mut guard = self.terminal.lock();
54        if guard.as_ref().is_some_and(|it| Arc::ptr_eq(it, term)) {
55            *guard = None;
56            true
57        } else {
58            false
59        }
60    }
61
62    /// Gets the terminal for this session, if it exists.
63    pub fn terminal(&self) -> Option<Arc<dyn Any + Send + Sync>> {
64        self.terminal.lock().clone()
65    }
66}
67
68impl fmt::Debug for Session {
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        write!(f, "Session({})", self.sid)
71    }
72}