signal.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. use core::sync::atomic::compiler_fence;
  2. use alloc::sync::Arc;
  3. use log::warn;
  4. use system_error::SystemError;
  5. use crate::{
  6. arch::ipc::signal::{SigCode, SigFlags, SigSet, Signal},
  7. ipc::signal_types::SigactionType,
  8. libs::spinlock::SpinLockGuard,
  9. process::{
  10. pid::PidType, Pid, ProcessControlBlock, ProcessFlags, ProcessManager, ProcessSignalInfo,
  11. },
  12. };
  13. use super::signal_types::{
  14. SaHandlerType, SigInfo, SigType, Sigaction, SignalStruct, SIG_KERNEL_STOP_MASK,
  15. };
  16. impl Signal {
  17. pub fn signal_pending_state(
  18. interruptible: bool,
  19. task_wake_kill: bool,
  20. pcb: &Arc<ProcessControlBlock>,
  21. ) -> bool {
  22. if !interruptible && !task_wake_kill {
  23. return false;
  24. }
  25. if !pcb.has_pending_signal_fast() {
  26. return false;
  27. }
  28. return interruptible || Self::fatal_signal_pending(pcb);
  29. }
  30. /// 判断当前进程是否收到了SIGKILL信号
  31. pub fn fatal_signal_pending(pcb: &Arc<ProcessControlBlock>) -> bool {
  32. let guard = pcb.sig_info_irqsave();
  33. if guard
  34. .sig_pending()
  35. .signal()
  36. .contains(Signal::SIGKILL.into())
  37. {
  38. return true;
  39. }
  40. return false;
  41. }
  42. /// 向目标进程发送信号
  43. ///
  44. /// ## 参数
  45. ///
  46. /// - `sig` 要发送的信号
  47. /// - `info` 要发送的信息
  48. /// - `pid` 进程id(目前只支持pid>0)
  49. pub fn send_signal_info(
  50. &self,
  51. info: Option<&mut SigInfo>,
  52. pid: Pid,
  53. ) -> Result<i32, SystemError> {
  54. // TODO:暂时不支持特殊的信号操作,待引入进程组后补充
  55. // 如果 pid 大于 0,那么会发送信号给 pid 指定的进程
  56. // 如果 pid 等于 0,那么会发送信号给与调用进程同组的每个进程,包括调用进程自身
  57. // 如果 pid 小于 -1,那么会向组 ID 等于该 pid 绝对值的进程组内所有下属进程发送信号。向一个进程组的所有进程发送信号在 shell 作业控制中有特殊有途
  58. // 如果 pid 等于 -1,那么信号的发送范围是:调用进程有权将信号发往的每个目标进程,除去 init(进程 ID 为 1)和调用进程自身。如果特权级进程发起这一调用,那么会发送信号给系统中的所有进程,上述两个进程除外。显而易见,有时也将这种信号发送方式称之为广播信号
  59. // 如果并无进程与指定的 pid 相匹配,那么 kill() 调用失败,同时将 errno 置为 ESRCH(“查无此进程”)
  60. if pid.lt(&Pid::from(0)) {
  61. warn!("Kill operation not support: pid={:?}", pid);
  62. return Err(SystemError::ENOSYS);
  63. }
  64. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  65. // 检查sig是否符合要求,如果不符合要求,则退出。
  66. if !self.is_valid() {
  67. return Err(SystemError::EINVAL);
  68. }
  69. let mut retval = Err(SystemError::ESRCH);
  70. let pcb = ProcessManager::find(pid);
  71. if pcb.is_none() {
  72. warn!("No such process.");
  73. return retval;
  74. }
  75. let pcb = pcb.unwrap();
  76. // println!("Target pcb = {:?}", pcb.as_ref().unwrap());
  77. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  78. // 发送信号
  79. retval = self.send_signal(info, pcb.clone(), PidType::PID);
  80. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  81. return retval;
  82. }
  83. /// @brief 判断是否需要强制发送信号,然后发送信号
  84. /// 进入函数后加锁
  85. ///
  86. /// @return SystemError 错误码
  87. fn send_signal(
  88. &self,
  89. info: Option<&mut SigInfo>,
  90. pcb: Arc<ProcessControlBlock>,
  91. pt: PidType,
  92. ) -> Result<i32, SystemError> {
  93. // 是否强制发送信号
  94. let mut force_send = false;
  95. // signal的信息为空
  96. if let Some(ref siginfo) = info {
  97. force_send = matches!(siginfo.sig_code(), SigCode::Kernel);
  98. } else {
  99. // todo: 判断signal是否来自于一个祖先进程的namespace,如果是,则强制发送信号
  100. //详见 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c?r=&mo=32170&fi=1220#1226
  101. }
  102. if !self.prepare_sianal(pcb.clone(), force_send) {
  103. return Ok(0);
  104. }
  105. // debug!("force send={}", force_send);
  106. let pcb_info = pcb.sig_info_irqsave();
  107. let pending = if matches!(pt, PidType::PID) {
  108. pcb_info.sig_shared_pending()
  109. } else {
  110. pcb_info.sig_pending()
  111. };
  112. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  113. // 如果是kill或者目标pcb是内核线程,则无需获取sigqueue,直接发送信号即可
  114. if matches!(self, Signal::SIGKILL) || pcb.flags().contains(ProcessFlags::KTHREAD) {
  115. //避免死锁
  116. drop(pcb_info);
  117. self.complete_signal(pcb.clone(), pt);
  118. }
  119. // 如果不是实时信号的话,同一时刻信号队列里只会有一个待处理的信号,如果重复接收就不做处理
  120. else if !self.is_rt_signal() && pending.queue().find(*self).0.is_some() {
  121. return Ok(0);
  122. } else {
  123. // TODO signalfd_notify 完善 signalfd 机制
  124. // 如果是其他信号,则加入到sigqueue内,然后complete_signal
  125. let new_sig_info = match info {
  126. Some(siginfo) => {
  127. // 已经显式指定了siginfo,则直接使用它。
  128. *siginfo
  129. }
  130. None => {
  131. // 不需要显示指定siginfo,因此设置为默认值
  132. SigInfo::new(
  133. *self,
  134. 0,
  135. SigCode::User,
  136. SigType::Kill(ProcessManager::current_pcb().pid()),
  137. )
  138. }
  139. };
  140. drop(pcb_info);
  141. pcb.sig_info_mut()
  142. .sig_pending_mut()
  143. .queue_mut()
  144. .q
  145. .push(new_sig_info);
  146. // if pt == PidType::PGID || pt == PidType::SID {}
  147. self.complete_signal(pcb.clone(), pt);
  148. }
  149. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  150. return Ok(0);
  151. }
  152. /// @brief 将信号添加到目标进程的sig_pending。在引入进程组后,本函数还将负责把信号传递给整个进程组。
  153. ///
  154. /// @param sig 信号
  155. /// @param pcb 目标pcb
  156. /// @param pt siginfo结构体中,pid字段代表的含义
  157. #[allow(clippy::if_same_then_else)]
  158. fn complete_signal(&self, pcb: Arc<ProcessControlBlock>, pt: PidType) {
  159. // debug!("complete_signal");
  160. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  161. // ===== 寻找需要wakeup的目标进程 =====
  162. // 备注:由于当前没有进程组的概念,每个进程只有1个对应的线程,因此不需要通知进程组内的每个进程。
  163. // todo: 当引入进程组的概念后,需要完善这里,使得它能寻找一个目标进程来唤醒,接着执行信号处理的操作。
  164. // let _signal = pcb.sig_struct();
  165. let target_pcb: Option<Arc<ProcessControlBlock>>;
  166. // 判断目标进程是否想接收这个信号
  167. if self.wants_signal(pcb.clone()) {
  168. // todo: 将信号产生的消息通知到正在监听这个信号的进程(引入signalfd之后,在这里调用signalfd_notify)
  169. // 将这个信号加到目标进程的sig_pending中
  170. pcb.sig_info_mut()
  171. .sig_pending_mut()
  172. .signal_mut()
  173. .insert((*self).into());
  174. target_pcb = Some(pcb.clone());
  175. } else if pt == PidType::PID {
  176. /*
  177. * There is just one thread and it does not need to be woken.
  178. * It will dequeue unblocked signals before it runs again.
  179. */
  180. return;
  181. } else {
  182. /*
  183. * Otherwise try to find a suitable thread.
  184. * 由于目前每个进程只有1个线程,因此当前情况可以返回。信号队列的dequeue操作不需要考虑同步阻塞的问题。
  185. */
  186. return;
  187. }
  188. // TODO:引入进程组后,在这里挑选一个进程来唤醒,让它执行相应的操作。
  189. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  190. // TODO: 到这里,信号已经被放置在共享的pending队列中,我们在这里把目标进程唤醒。
  191. if let Some(target_pcb) = target_pcb {
  192. let guard = target_pcb.sig_struct();
  193. signal_wake_up(target_pcb.clone(), guard, *self == Signal::SIGKILL);
  194. }
  195. }
  196. /// 本函数用于检测指定的进程是否想要接收SIG这个信号。
  197. ///
  198. /// 当我们对于进程组中的所有进程都运行了这个检查之后,我们将可以找到组内愿意接收信号的进程。
  199. /// 这么做是为了防止我们把信号发送给了一个正在或已经退出的进程,或者是不响应该信号的进程。
  200. #[inline]
  201. fn wants_signal(&self, pcb: Arc<ProcessControlBlock>) -> bool {
  202. // 如果改进程屏蔽了这个signal,则不能接收
  203. if pcb
  204. .sig_info_irqsave()
  205. .sig_blocked()
  206. .contains((*self).into())
  207. {
  208. return false;
  209. }
  210. // 如果进程正在退出,则不能接收信号
  211. if pcb.flags().contains(ProcessFlags::EXITING) {
  212. return false;
  213. }
  214. if *self == Signal::SIGKILL {
  215. return true;
  216. }
  217. let state = pcb.sched_info().inner_lock_read_irqsave().state();
  218. if state.is_blocked() && (!state.is_blocked_interruptable()) {
  219. return false;
  220. }
  221. // todo: 检查目标进程是否正在一个cpu上执行,如果是,则返回true,否则继续检查下一项
  222. // 检查目标进程是否有信号正在等待处理,如果是,则返回false,否则返回true
  223. return pcb.sig_info_irqsave().sig_pending().signal().bits() == 0;
  224. }
  225. /// @brief 判断signal的处理是否可能使得整个进程组退出
  226. /// @return true 可能会导致退出(不一定)
  227. #[allow(dead_code)]
  228. #[inline]
  229. fn sig_fatal(&self, pcb: Arc<ProcessControlBlock>) -> bool {
  230. let action = pcb.sig_struct().handlers[*self as usize - 1].action();
  231. // 如果handler是空,采用默认函数,signal处理可能会导致进程退出。
  232. match action {
  233. SigactionType::SaHandler(handler) => handler.is_sig_default(),
  234. SigactionType::SaSigaction(sigaction) => sigaction.is_none(),
  235. }
  236. // todo: 参照linux的sig_fatal实现完整功能
  237. }
  238. /// 检查信号是否能被发送,并且而且要处理 SIGCONT 和 STOP 信号
  239. ///
  240. /// ## 参数
  241. ///
  242. /// - `pcb` 要发送信号的目标pcb
  243. ///
  244. /// - `force` 是否强制发送(指走 fast path , 不加入 sigpending按顺序处理,直接进入 complete_signal)
  245. ///
  246. /// ## 返回值
  247. ///
  248. /// - `true` 能够发送信号
  249. ///
  250. /// - `false` 不能发送信号
  251. fn prepare_sianal(&self, pcb: Arc<ProcessControlBlock>, _force: bool) -> bool {
  252. let flush: SigSet;
  253. if !(self.into_sigset() & SIG_KERNEL_STOP_MASK).is_empty() {
  254. flush = Signal::SIGCONT.into_sigset();
  255. pcb.sig_info_mut()
  256. .sig_shared_pending_mut()
  257. .flush_by_mask(&flush);
  258. // TODO 对每个子线程 flush mask
  259. } else if *self == Signal::SIGCONT {
  260. flush = SIG_KERNEL_STOP_MASK;
  261. assert!(!flush.is_empty());
  262. pcb.sig_info_mut()
  263. .sig_shared_pending_mut()
  264. .flush_by_mask(&flush);
  265. let _r = ProcessManager::wakeup_stop(&pcb);
  266. // TODO 对每个子线程 flush mask
  267. // 这里需要补充一段逻辑,详见https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#952
  268. }
  269. // 一个被阻塞了的信号肯定是要被处理的
  270. if pcb
  271. .sig_info_irqsave()
  272. .sig_blocked()
  273. .contains(self.into_sigset())
  274. {
  275. return true;
  276. }
  277. return !pcb.sig_struct().handlers[*self as usize - 1].is_ignore();
  278. //TODO 仿照 linux 中的prepare signal完善逻辑,linux 中还会根据例如当前进程状态(Existing)进行判断,现在的信号能否发出就只是根据 ignored 来判断
  279. }
  280. }
  281. /// 因收到信号而唤醒进程
  282. ///
  283. /// ## 参数
  284. ///
  285. /// - `pcb` 要唤醒的进程pcb
  286. /// - `_guard` 信号结构体锁守卫,来保证信号结构体已上锁
  287. /// - `fatal` 表明这个信号是不是致命的(会导致进程退出)
  288. #[inline]
  289. fn signal_wake_up(pcb: Arc<ProcessControlBlock>, _guard: SpinLockGuard<SignalStruct>, fatal: bool) {
  290. // 如果是 fatal 的话就唤醒 stop 和 block 的进程来响应,因为唤醒后就会终止
  291. // 如果不是 fatal 的就只唤醒 stop 的进程来响应
  292. // debug!("signal_wake_up");
  293. // 如果目标进程已经在运行,则发起一个ipi,使得它陷入内核
  294. let state = pcb.sched_info().inner_lock_read_irqsave().state();
  295. pcb.flags().insert(ProcessFlags::HAS_PENDING_SIGNAL);
  296. let mut wakeup_ok = true;
  297. if state.is_blocked_interruptable() {
  298. ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
  299. wakeup_ok = false;
  300. warn!(
  301. "Current pid: {:?}, signal_wake_up target {:?} error: {:?}",
  302. ProcessManager::current_pcb().pid(),
  303. pcb.pid(),
  304. e
  305. );
  306. });
  307. } else if state.is_stopped() {
  308. ProcessManager::wakeup_stop(&pcb).unwrap_or_else(|e| {
  309. wakeup_ok = false;
  310. warn!(
  311. "Current pid: {:?}, signal_wake_up target {:?} error: {:?}",
  312. ProcessManager::current_pcb().pid(),
  313. pcb.pid(),
  314. e
  315. );
  316. });
  317. } else {
  318. wakeup_ok = false;
  319. }
  320. if wakeup_ok {
  321. ProcessManager::kick(&pcb);
  322. } else if fatal {
  323. let _r = ProcessManager::wakeup(&pcb).map(|_| {
  324. ProcessManager::kick(&pcb);
  325. });
  326. }
  327. }
  328. fn has_pending_signals(sigset: &SigSet, blocked: &SigSet) -> bool {
  329. sigset.bits() & (!blocked.bits()) != 0
  330. }
  331. impl ProcessControlBlock {
  332. /// 重新计算线程的flag中的TIF_SIGPENDING位
  333. /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c?r=&mo=4806&fi=182#182
  334. pub fn recalc_sigpending(&self, siginfo_guard: Option<&ProcessSignalInfo>) {
  335. if !self.recalc_sigpending_tsk(siginfo_guard) {
  336. self.flags().remove(ProcessFlags::HAS_PENDING_SIGNAL);
  337. }
  338. }
  339. fn recalc_sigpending_tsk(&self, siginfo_guard: Option<&ProcessSignalInfo>) -> bool {
  340. let mut _siginfo_tmp_guard = None;
  341. let siginfo = if let Some(siginfo_guard) = siginfo_guard {
  342. siginfo_guard
  343. } else {
  344. _siginfo_tmp_guard = Some(self.sig_info_irqsave());
  345. _siginfo_tmp_guard.as_ref().unwrap()
  346. };
  347. return siginfo.do_recalc_sigpending_tsk(self);
  348. }
  349. }
  350. impl ProcessSignalInfo {
  351. fn do_recalc_sigpending_tsk(&self, pcb: &ProcessControlBlock) -> bool {
  352. if has_pending_signals(&self.sig_pending().signal(), self.sig_blocked())
  353. || has_pending_signals(&self.sig_shared_pending().signal(), self.sig_blocked())
  354. {
  355. pcb.flags().insert(ProcessFlags::HAS_PENDING_SIGNAL);
  356. return true;
  357. }
  358. /*
  359. * We must never clear the flag in another thread, or in current
  360. * when it's possible the current syscall is returning -ERESTART*.
  361. * So we don't clear it here, and only callers who know they should do.
  362. */
  363. return false;
  364. }
  365. }
  366. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/sched/signal.h?fi=restore_saved_sigmask#547
  367. pub fn restore_saved_sigmask() {
  368. if ProcessManager::current_pcb()
  369. .flags()
  370. .test_and_clear(ProcessFlags::RESTORE_SIG_MASK)
  371. {
  372. let saved = *ProcessManager::current_pcb()
  373. .sig_info_irqsave()
  374. .saved_sigmask();
  375. __set_current_blocked(&saved);
  376. }
  377. }
  378. /// 刷新指定进程的sighand的sigaction,将满足条件的sigaction恢复为默认状态。
  379. /// 除非某个信号被设置为忽略且 `force_default` 为 `false`,否则都不会将其恢复。
  380. ///
  381. /// # 参数
  382. ///
  383. /// - `pcb`: 要被刷新的pcb。
  384. /// - `force_default`: 是否强制将sigaction恢复成默认状态。
  385. pub fn flush_signal_handlers(pcb: Arc<ProcessControlBlock>, force_default: bool) {
  386. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  387. // debug!("hand=0x{:018x}", hand as *const sighand_struct as usize);
  388. let actions = &mut pcb.sig_struct_irqsave().handlers;
  389. for sigaction in actions.iter_mut() {
  390. if force_default || !sigaction.is_ignore() {
  391. sigaction.set_action(SigactionType::SaHandler(SaHandlerType::Default));
  392. }
  393. // 清除flags中,除了DFL和IGN以外的所有标志
  394. sigaction.set_restorer(None);
  395. sigaction.mask_mut().remove(SigSet::all());
  396. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  397. }
  398. compiler_fence(core::sync::atomic::Ordering::SeqCst);
  399. }
  400. pub(super) fn do_sigaction(
  401. sig: Signal,
  402. act: Option<&mut Sigaction>,
  403. old_act: Option<&mut Sigaction>,
  404. ) -> Result<(), SystemError> {
  405. if sig == Signal::INVALID {
  406. return Err(SystemError::EINVAL);
  407. }
  408. let pcb = ProcessManager::current_pcb();
  409. // 指向当前信号的action的引用
  410. let action: &mut Sigaction = &mut pcb.sig_struct().handlers[sig as usize - 1];
  411. // 对比 MUSL 和 relibc , 暂时不设置这个标志位
  412. // if action.flags().contains(SigFlags::SA_FLAG_IMMUTABLE) {
  413. // return Err(SystemError::EINVAL);
  414. // }
  415. // 保存原有的 sigaction
  416. let old_act: Option<&mut Sigaction> = {
  417. if let Some(oa) = old_act {
  418. *(oa) = *action;
  419. Some(oa)
  420. } else {
  421. None
  422. }
  423. };
  424. // 清除所有的脏的sa_flags位(也就是清除那些未使用的)
  425. let act = {
  426. if let Some(ac) = act {
  427. *ac.flags_mut() &= SigFlags::SA_ALL;
  428. Some(ac)
  429. } else {
  430. None
  431. }
  432. };
  433. if let Some(act) = old_act {
  434. *act.flags_mut() &= SigFlags::SA_ALL;
  435. }
  436. if let Some(ac) = act {
  437. // 将act.sa_mask的SIGKILL SIGSTOP的屏蔽清除
  438. ac.mask_mut()
  439. .remove(<Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into());
  440. // 将新的sigaction拷贝到进程的action中
  441. *action = *ac;
  442. /*
  443. * 根据POSIX 3.3.1.3规定:
  444. * 1.不管一个信号是否被阻塞,只要将其设置SIG_IGN,如果当前已经存在了正在pending的信号,那么就把这个信号忽略。
  445. *
  446. * 2.不管一个信号是否被阻塞,只要将其设置SIG_DFL,如果当前已经存在了正在pending的信号,
  447. 并且对这个信号的默认处理方式是忽略它,那么就会把pending的信号忽略。
  448. */
  449. if action.is_ignore() {
  450. let mut mask: SigSet = SigSet::from_bits_truncate(0);
  451. mask.insert(sig.into());
  452. pcb.sig_info_mut().sig_pending_mut().flush_by_mask(&mask);
  453. // todo: 当有了多个线程后,在这里进行操作,把每个线程的sigqueue都进行刷新
  454. }
  455. }
  456. return Ok(());
  457. }
  458. /// https://code.dragonos.org.cn/xref/linux-6.6.21/include/uapi/asm-generic/signal-defs.h#72
  459. /// 对应SIG_BLOCK,SIG_UNBLOCK,SIG_SETMASK
  460. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  461. pub enum SigHow {
  462. Block = 0,
  463. Unblock = 1,
  464. SetMask = 2,
  465. }
  466. impl TryFrom<i32> for SigHow {
  467. type Error = SystemError;
  468. fn try_from(value: i32) -> Result<Self, Self::Error> {
  469. match value {
  470. 0 => Ok(SigHow::Block),
  471. 1 => Ok(SigHow::Unblock),
  472. 2 => Ok(SigHow::SetMask),
  473. _ => Err(SystemError::EINVAL),
  474. }
  475. }
  476. }
  477. fn __set_task_blocked(pcb: &Arc<ProcessControlBlock>, new_set: &SigSet) {
  478. //todo 还有一个对线程组是否为空的判断,进程组、线程组实现之后,需要更改这里。
  479. if pcb.has_pending_signal() {
  480. let mut newblocked = *new_set;
  481. let guard = pcb.sig_info_irqsave();
  482. newblocked.remove(*guard.sig_blocked());
  483. drop(guard);
  484. // 从主线程开始去遍历
  485. if let Some(group_leader) = pcb.threads_read_irqsave().group_leader() {
  486. retarget_shared_pending(group_leader, newblocked);
  487. }
  488. }
  489. *pcb.sig_info_mut().sig_block_mut() = *new_set;
  490. pcb.recalc_sigpending(None);
  491. }
  492. fn __set_current_blocked(new_set: &SigSet) {
  493. let pcb = ProcessManager::current_pcb();
  494. /*
  495. 如果当前pcb的sig_blocked和新的相等,那么就不用改变它。
  496. 请注意,一个进程的sig_blocked字段不能被其他进程修改!
  497. */
  498. if pcb.sig_info_irqsave().sig_blocked().eq(new_set) {
  499. return;
  500. }
  501. let guard: SpinLockGuard<'_, SignalStruct> = pcb.sig_struct_irqsave();
  502. __set_task_blocked(&pcb, new_set);
  503. drop(guard);
  504. }
  505. fn retarget_shared_pending(pcb: Arc<ProcessControlBlock>, which: SigSet) {
  506. let retarget = pcb.sig_info_irqsave().sig_shared_pending().signal();
  507. retarget.intersects(which);
  508. if retarget.is_empty() {
  509. return;
  510. }
  511. // 对于线程组中的每一个线程都要执行的函数
  512. let thread_handling_function = |pcb: Arc<ProcessControlBlock>, retarget: &SigSet| {
  513. if retarget.is_empty() {
  514. return;
  515. }
  516. if pcb.flags().contains(ProcessFlags::EXITING) {
  517. return;
  518. }
  519. let blocked = pcb.sig_info_irqsave().sig_shared_pending().signal();
  520. if retarget.difference(blocked).is_empty() {
  521. return;
  522. }
  523. retarget.intersects(blocked);
  524. if !pcb.has_pending_signal() {
  525. let guard = pcb.sig_struct_irqsave();
  526. signal_wake_up(pcb.clone(), guard, false);
  527. }
  528. // 之前的对retarget的判断移动到最前面,因为对于当前线程的线程的处理已经结束,对于后面的线程在一开始判断retarget为空即可结束处理
  529. // debug!("handle done");
  530. };
  531. // 暴力遍历每一个线程,找到相同的tgid
  532. let tgid = pcb.tgid();
  533. for &pid in pcb.children_read_irqsave().iter() {
  534. if let Some(child) = ProcessManager::find(pid) {
  535. if child.tgid() == tgid {
  536. thread_handling_function(child, &retarget);
  537. }
  538. }
  539. }
  540. // debug!("retarget_shared_pending done!");
  541. }
  542. /// 设置当前进程的屏蔽信号 (sig_block)
  543. ///
  544. /// ## 参数
  545. ///
  546. /// - `new_set` 新的屏蔽信号bitmap的值
  547. pub fn set_current_blocked(new_set: &mut SigSet) {
  548. let to_remove: SigSet =
  549. <Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into();
  550. new_set.remove(to_remove);
  551. __set_current_blocked(new_set);
  552. }
  553. /// 设置当前进程的屏蔽信号 (sig_block)
  554. ///
  555. /// ## 参数
  556. ///
  557. /// - `how` 设置方式
  558. /// - `new_set` 新的屏蔽信号bitmap的值
  559. pub fn set_sigprocmask(how: SigHow, set: SigSet) -> Result<SigSet, SystemError> {
  560. let pcb: Arc<ProcessControlBlock> = ProcessManager::current_pcb();
  561. let guard = pcb.sig_info_irqsave();
  562. let oset = *guard.sig_blocked();
  563. let mut res_set = oset;
  564. drop(guard);
  565. match how {
  566. SigHow::Block => {
  567. // debug!("SIG_BLOCK\tGoing to insert is: {}", set.bits());
  568. res_set.insert(set);
  569. }
  570. SigHow::Unblock => {
  571. res_set.remove(set);
  572. }
  573. SigHow::SetMask => {
  574. // debug!("SIG_SETMASK\tGoing to set is: {}", set.bits());
  575. res_set = set;
  576. }
  577. }
  578. __set_current_blocked(&res_set);
  579. Ok(oset)
  580. }