starnix_core/task/
session.rs1use macro_rules_attribute::apply;
6use starnix_sync::RwLock;
7use std::collections::BTreeMap;
8use std::sync::{Arc, Weak};
9
10use crate::device::terminal::Terminal;
11use crate::mutable_state::{state_accessor, state_implementation};
12use crate::task::ProcessGroup;
13use starnix_uapi::pid_t;
14
15#[derive(Debug)]
16pub struct SessionMutableState {
17 process_groups: BTreeMap<pid_t, Weak<ProcessGroup>>,
24
25 foreground_process_group: pid_t,
28
29 pub controlling_terminal: Option<ControllingTerminal>,
31}
32
33#[derive(Debug)]
46pub struct Session {
47 pub leader: pid_t,
49
50 mutable_state: RwLock<SessionMutableState>,
52}
53
54impl PartialEq for Session {
55 fn eq(&self, other: &Self) -> bool {
56 self.leader == other.leader
57 }
58}
59
60impl Session {
61 pub fn new(leader: pid_t) -> Arc<Session> {
62 Arc::new(Session {
63 leader,
64 mutable_state: RwLock::new(SessionMutableState {
65 process_groups: BTreeMap::new(),
66 foreground_process_group: leader,
67 controlling_terminal: None,
68 }),
69 })
70 }
71
72 state_accessor!(Session, mutable_state);
73}
74
75#[apply(state_implementation!)]
76impl SessionMutableState<Base = Session> {
77 pub fn remove(&mut self, pid: pid_t) {
79 self.process_groups.remove(&pid);
80 }
81
82 pub fn insert(&mut self, process_group: &Arc<ProcessGroup>) {
83 self.process_groups.insert(process_group.leader, Arc::downgrade(process_group));
84 }
85
86 pub fn get_foreground_process_group_leader(&self) -> pid_t {
87 self.foreground_process_group
88 }
89
90 pub fn get_foreground_process_group(&self) -> Option<Arc<ProcessGroup>> {
91 self.process_groups.get(&self.foreground_process_group).and_then(Weak::upgrade)
92 }
93
94 pub fn set_foreground_process_group(&mut self, process_group: &Arc<ProcessGroup>) {
95 self.foreground_process_group = process_group.leader;
96 }
97}
98
99#[derive(Clone, Debug)]
101pub struct ControllingTerminal {
102 pub terminal: Arc<Terminal>,
104 pub is_main: bool,
106}
107
108impl ControllingTerminal {
109 pub fn new(terminal: &Terminal, is_main: bool) -> Self {
110 Self { terminal: terminal.to_owned(), is_main }
111 }
112
113 pub fn matches(&self, terminal: &Terminal, is_main: bool) -> bool {
114 std::ptr::eq(terminal, Arc::as_ptr(&self.terminal)) && is_main == self.is_main
115 }
116}