session.rs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. use super::{
  2. process_group::{Pgid, ProcessGroup},
  3. Pid, ProcessControlBlock, ProcessManager,
  4. };
  5. use crate::libs::spinlock::SpinLock;
  6. use alloc::{
  7. collections::BTreeMap,
  8. sync::{Arc, Weak},
  9. };
  10. use hashbrown::HashMap;
  11. use system_error::SystemError;
  12. /// 会话SID
  13. pub type Sid = Pid;
  14. /// 系统中所有会话
  15. pub static ALL_SESSION: SpinLock<Option<HashMap<Sid, Arc<Session>>>> = SpinLock::new(None);
  16. #[derive(Debug)]
  17. pub struct Session {
  18. pub sid: Sid,
  19. pub session_inner: SpinLock<SessionInner>,
  20. }
  21. #[derive(Debug)]
  22. pub struct SessionInner {
  23. pub process_groups: BTreeMap<Pgid, Arc<ProcessGroup>>,
  24. pub leader: Option<Arc<ProcessControlBlock>>,
  25. }
  26. impl SessionInner {
  27. pub fn is_empty(&self) -> bool {
  28. self.process_groups.is_empty()
  29. }
  30. pub fn remove_process_group(&mut self, pgid: &Pgid) {
  31. self.process_groups.remove(pgid);
  32. }
  33. pub fn remove_process(&mut self, pcb: &Arc<ProcessControlBlock>) {
  34. if let Some(leader) = &self.leader {
  35. if Arc::ptr_eq(leader, pcb) {
  36. self.leader = None;
  37. }
  38. }
  39. }
  40. pub fn should_destory(&self) -> bool {
  41. self.process_groups.is_empty()
  42. }
  43. }
  44. impl Session {
  45. pub fn new(group: Arc<ProcessGroup>) -> Arc<Self> {
  46. let sid = group.pgid;
  47. let mut process_groups = BTreeMap::new();
  48. process_groups.insert(group.pgid, group.clone());
  49. let inner = SessionInner {
  50. process_groups,
  51. leader: None,
  52. };
  53. // log::debug!("New Session {:?}", sid);
  54. Arc::new(Self {
  55. sid,
  56. session_inner: SpinLock::new(inner),
  57. })
  58. }
  59. pub fn sid(&self) -> Sid {
  60. self.sid
  61. }
  62. pub fn leader(&self) -> Option<Arc<ProcessControlBlock>> {
  63. self.session_inner.lock().leader.clone()
  64. }
  65. // pub fn contains_process_group(&self, pgid: Pgid) -> bool {
  66. // self.session_inner.lock().process_groups.contains_key(&pgid)
  67. // }
  68. pub fn contains_process_group(&self, process_group: &Arc<ProcessGroup>) -> bool {
  69. self.session_inner
  70. .lock()
  71. .process_groups
  72. .contains_key(&process_group.pgid)
  73. }
  74. }
  75. impl Drop for Session {
  76. fn drop(&mut self) {
  77. let mut session_inner = self.session_inner.lock();
  78. session_inner.process_groups.clear();
  79. session_inner.leader = None;
  80. // log::debug!("Dropping session: {:?}", self.sid());
  81. }
  82. }
  83. impl ProcessManager {
  84. /// 根据sid获取会话
  85. ///
  86. /// ## 参数
  87. ///
  88. /// - `sid` : 会话的sid
  89. ///
  90. /// ## 返回值
  91. ///
  92. /// 如果找到了对应的会话,那么返回该会话,否则返回None
  93. pub fn find_session(sid: Sid) -> Option<Arc<Session>> {
  94. return ALL_SESSION.lock_irqsave().as_ref()?.get(&sid).cloned();
  95. }
  96. /// 向系统中添加一个会话
  97. ///
  98. /// ## 参数
  99. ///
  100. /// - `session` : Arc<Session>
  101. ///
  102. /// ## 返回值
  103. ///
  104. /// 无
  105. pub fn add_session(session: Arc<Session>) {
  106. ALL_SESSION
  107. .lock_irqsave()
  108. .as_mut()
  109. .unwrap()
  110. .insert(session.sid(), session.clone());
  111. // log::debug!("New Session added, sid: {:?}", session.sid());
  112. }
  113. pub fn remove_session(sid: Sid) {
  114. // log::debug!("Removing session: {:?}", sid.clone());
  115. let mut all_sessions = ALL_SESSION.lock_irqsave();
  116. if let Some(session) = all_sessions.as_mut().unwrap().remove(&sid) {
  117. if Arc::strong_count(&session) <= 2 {
  118. // 这里 Arc 计数为 1,意味着它只有在 all_groups 里有一个引用,移除后会自动释放
  119. drop(session);
  120. }
  121. }
  122. }
  123. }
  124. impl ProcessControlBlock {
  125. pub fn session(&self) -> Option<Arc<Session>> {
  126. let pg = self.process_group()?;
  127. pg.session()
  128. }
  129. pub fn is_session_leader(&self) -> bool {
  130. if let Some(pcb) = self.self_ref.upgrade() {
  131. let session = pcb.session().unwrap();
  132. if let Some(leader) = session.leader() {
  133. return Arc::ptr_eq(&pcb, &leader);
  134. }
  135. }
  136. return false;
  137. }
  138. /// 将进程移动到新会话中
  139. /// 如果进程已经是会话领导者,则返回当前会话
  140. /// 如果不是,则主动创建一个新会话,并将进程移动到新会话中,返回新会话
  141. ///
  142. /// ## 返回值
  143. ///
  144. /// 新会话
  145. pub fn go_to_new_session(&self) -> Result<Arc<Session>, SystemError> {
  146. if self.is_session_leader() {
  147. return Ok(self.session().unwrap());
  148. }
  149. if self.is_process_group_leader() {
  150. return Err(SystemError::EPERM);
  151. }
  152. let session = self.session().unwrap();
  153. let mut self_group = self.process_group.lock();
  154. if ProcessManager::find_session(self.pid()).is_some() {
  155. return Err(SystemError::EPERM);
  156. }
  157. if ProcessManager::find_process_group(self.pid).is_some() {
  158. return Err(SystemError::EPERM);
  159. }
  160. if let Some(old_pg) = self_group.upgrade() {
  161. let mut old_pg_inner = old_pg.process_group_inner.lock();
  162. let mut session_inner = session.session_inner.lock();
  163. old_pg_inner.remove_process(&self.pid);
  164. *self_group = Weak::new();
  165. if old_pg_inner.is_empty() {
  166. ProcessManager::remove_process_group(old_pg.pgid());
  167. assert!(session_inner.process_groups.contains_key(&old_pg.pgid()));
  168. session_inner.process_groups.remove(&old_pg.pgid());
  169. if session_inner.is_empty() {
  170. ProcessManager::remove_session(session.sid());
  171. }
  172. }
  173. }
  174. let pcb = self.self_ref.upgrade().unwrap();
  175. let new_pg = ProcessGroup::new(pcb.clone());
  176. *self_group = Arc::downgrade(&new_pg);
  177. ProcessManager::add_process_group(new_pg.clone());
  178. let new_session = Session::new(new_pg.clone());
  179. let mut new_pg_inner = new_pg.process_group_inner.lock();
  180. new_pg_inner.session = Arc::downgrade(&new_session);
  181. new_session.session_inner.lock().leader = Some(pcb.clone());
  182. ProcessManager::add_session(new_session.clone());
  183. let mut session_inner = session.session_inner.lock();
  184. session_inner.remove_process(&pcb);
  185. Ok(new_session)
  186. }
  187. pub fn sid(&self) -> Sid {
  188. if let Some(session) = self.session() {
  189. return session.sid();
  190. }
  191. return Sid::new(1);
  192. }
  193. }