From 5a80d4e1a34c94204a0bb01443bf25a4fdb12750 Mon Sep 17 00:00:00 2001
From: Guangyao Ma <guangyao.ma@outlook.com>
Date: Thu, 26 Aug 2021 15:16:32 +0800
Subject: [PATCH] fix: solve SIGCHLD ignored in sigsuspend()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

在如下场景signal可能得不到及时处理:
1、进程A设置信号a阻塞
2、进程A收到信号a
3、进程A调用sigsuspend结束阻塞
原则上,步骤三应该立刻处理之前被阻塞的信号a,调用信号处理函数,并且sigsuspend
返回。现在的问题是,信号a没有得到及时处理,并且进程A阻塞在sigsuspend()调用流程
。
本次修改,在1、2、3场景下,sigsuspend()处理过程中,如果发现已经收到信号,待处理
时,会立刻进行调度切换,再次调度回来时,在调度模块中,会先主动处理已经收到的信
号,最后sigsuspend返回用户态。

close #I47CKK

Signed-off-by: Guangyao Ma <guangyao.ma@outlook.com>
Change-Id: I1b30a938a2d18c3f58989d40eee0503ceffb27b5
---
 kernel/base/ipc/los_signal.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c
index 06fee687..2c7f72e6 100644
--- a/kernel/base/ipc/los_signal.c
+++ b/kernel/base/ipc/los_signal.c
@@ -562,9 +562,21 @@ int OsSigSuspend(const sigset_t *set)
 
     /* If pending mask not in sigmask, need set sigflag */
     OsSigMaskSwitch(rtcb, *set);
-    ret = OsSigTimedWaitNoLock(&setSuspend, NULL, LOS_WAIT_FOREVER);
-    if (ret < 0) {
-        PRINT_ERR("FUNC %s LINE = %d, ret = %x\n", __FUNCTION__, __LINE__, ret);
+
+    if (rtcb->sig.sigFlag > 0) {
+        SCHEDULER_UNLOCK(intSave);
+
+        /*
+         * If rtcb->sig.sigFlag > 0, it means that some signal have been
+         * received, and we need to do schedule to handle the signal directly.
+         */
+        LOS_Schedule();
+        return -EINTR;
+    } else {
+        ret = OsSigTimedWaitNoLock(&setSuspend, NULL, LOS_WAIT_FOREVER);
+        if (ret < 0) {
+            PRINT_ERR("FUNC %s LINE = %d, ret = %x\n", __FUNCTION__, __LINE__, ret);
+        }
     }
 
     SCHEDULER_UNLOCK(intSave);