!520 修复sigwait等待到的信号值与获取的siginfo中的值不一致
Merge pull request !520 from lnlan/fixed_sigwait
This commit is contained in:
commit
93e74c5f0b
|
@ -498,6 +498,7 @@ LITE_OS_SEC_TEXT VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
|
||||||
OsTaskKernelResourcesToFree(syncSignal, topOfStack);
|
OsTaskKernelResourcesToFree(syncSignal, topOfStack);
|
||||||
|
|
||||||
SCHEDULER_LOCK(intSave);
|
SCHEDULER_LOCK(intSave);
|
||||||
|
OsClearSigInfoTmpList(&(taskCB->sig));
|
||||||
OsInsertTCBToFreeList(taskCB);
|
OsInsertTCBToFreeList(taskCB);
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,11 @@ struct sq_queue_s {
|
||||||
};
|
};
|
||||||
typedef struct sq_queue_s sq_queue_t;
|
typedef struct sq_queue_s sq_queue_t;
|
||||||
|
|
||||||
|
typedef struct SigInfoListNode {
|
||||||
|
struct SigInfoListNode *next;
|
||||||
|
siginfo_t info;
|
||||||
|
} SigInfoListNode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
sigset_t sigFlag;
|
sigset_t sigFlag;
|
||||||
sigset_t sigPendFlag;
|
sigset_t sigPendFlag;
|
||||||
|
@ -140,6 +145,7 @@ typedef struct {
|
||||||
LOS_DL_LIST waitList;
|
LOS_DL_LIST waitList;
|
||||||
sigset_t sigwaitmask; /* Waiting for pending signals */
|
sigset_t sigwaitmask; /* Waiting for pending signals */
|
||||||
siginfo_t sigunbinfo; /* Signal info when task unblocked */
|
siginfo_t sigunbinfo; /* Signal info when task unblocked */
|
||||||
|
SigInfoListNode *tmpInfoListHead; /* Signal info List */
|
||||||
unsigned int sigIntLock;
|
unsigned int sigIntLock;
|
||||||
void *sigContext;
|
void *sigContext;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
@ -167,6 +173,7 @@ int OsSigSuspend(const sigset_t *set);
|
||||||
VOID OsSigIntLock(VOID);
|
VOID OsSigIntLock(VOID);
|
||||||
VOID OsSigIntUnlock(VOID);
|
VOID OsSigIntUnlock(VOID);
|
||||||
INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo);
|
INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo);
|
||||||
|
VOID OsClearSigInfoTmpList(sig_cb *sigcb);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|
|
@ -67,11 +67,60 @@ int OsSigIsMember(const sigset_t *set, int signo)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC VOID OsMoveTmpInfoToUnbInfo(sig_cb *sigcb, INT32 signo)
|
||||||
|
{
|
||||||
|
SigInfoListNode *tmpInfoNode = sigcb->tmpInfoListHead;
|
||||||
|
SigInfoListNode **prevHook = &sigcb->tmpInfoListHead;
|
||||||
|
INT32 isFirstDel = 1;
|
||||||
|
while (tmpInfoNode != NULL) {
|
||||||
|
if (tmpInfoNode->info.si_signo == signo) {
|
||||||
|
/* In some case, many siginfos have same signo, only last one inserted list need copy to unbinfo. */
|
||||||
|
if (isFirstDel) {
|
||||||
|
/* copy tmpinfo to unbinfo. */
|
||||||
|
(VOID)memcpy_s(&sigcb->sigunbinfo, sizeof(siginfo_t), &tmpInfoNode->info, sizeof(siginfo_t));
|
||||||
|
isFirstDel = 0;
|
||||||
|
}
|
||||||
|
/* delete tmpinfo from tmpList. */
|
||||||
|
*prevHook = tmpInfoNode->next;
|
||||||
|
(VOID)LOS_MemFree(m_aucSysMem0, tmpInfoNode);
|
||||||
|
tmpInfoNode = *prevHook;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
prevHook = &tmpInfoNode->next;
|
||||||
|
tmpInfoNode = tmpInfoNode->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC INT32 OsAddSigInfoToTmpList(sig_cb *sigcb, siginfo_t *info)
|
||||||
|
{
|
||||||
|
SigInfoListNode *tmp = (SigInfoListNode *)LOS_MemAlloc(m_aucSysMem0, sizeof(SigInfoListNode));
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return LOS_NOK;
|
||||||
|
}
|
||||||
|
(VOID)memcpy_s(&tmp->info, sizeof(siginfo_t), info, sizeof(siginfo_t));
|
||||||
|
tmp->next = sigcb->tmpInfoListHead;
|
||||||
|
sigcb->tmpInfoListHead = tmp;
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID OsClearSigInfoTmpList(sig_cb *sigcb)
|
||||||
|
{
|
||||||
|
while (sigcb->tmpInfoListHead != NULL) {
|
||||||
|
SigInfoListNode *tmpInfoNode = sigcb->tmpInfoListHead;
|
||||||
|
sigcb->tmpInfoListHead = sigcb->tmpInfoListHead->next;
|
||||||
|
(VOID)LOS_MemFree(m_aucSysMem0, tmpInfoNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo)
|
STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo)
|
||||||
{
|
{
|
||||||
sig_cb *sigcb = &taskCB->sig;
|
sig_cb *sigcb = &taskCB->sig;
|
||||||
|
|
||||||
if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, signo)) {
|
if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, signo)) {
|
||||||
|
OsMoveTmpInfoToUnbInfo(sigcb, signo);
|
||||||
OsTaskWakeClearPendMask(taskCB);
|
OsTaskWakeClearPendMask(taskCB);
|
||||||
OsSchedTaskWake(taskCB);
|
OsSchedTaskWake(taskCB);
|
||||||
OsSigEmptySet(&sigcb->sigwaitmask);
|
OsSigEmptySet(&sigcb->sigwaitmask);
|
||||||
|
@ -141,7 +190,10 @@ int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info)
|
||||||
/* unmasked signal actions */
|
/* unmasked signal actions */
|
||||||
OsSigAddSet(&sigcb->sigFlag, info->si_signo);
|
OsSigAddSet(&sigcb->sigFlag, info->si_signo);
|
||||||
}
|
}
|
||||||
(void) memcpy_s(&sigcb->sigunbinfo, sizeof(siginfo_t), info, sizeof(siginfo_t));
|
|
||||||
|
if (OsAddSigInfoToTmpList(sigcb, info) == LOS_NOK) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
return OsPendingTaskWake(stcb, info->si_signo);
|
return OsPendingTaskWake(stcb, info->si_signo);
|
||||||
}
|
}
|
||||||
|
@ -516,6 +568,7 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
|
||||||
if (clear) {
|
if (clear) {
|
||||||
sigcb->sigPendFlag ^= clear;
|
sigcb->sigPendFlag ^= clear;
|
||||||
ret = FindFirstSetedBit((UINT64)clear) + 1;
|
ret = FindFirstSetedBit((UINT64)clear) + 1;
|
||||||
|
OsMoveTmpInfoToUnbInfo(sigcb, ret);
|
||||||
} else {
|
} else {
|
||||||
OsSigAddSet(set, SIGKILL);
|
OsSigAddSet(set, SIGKILL);
|
||||||
OsSigAddSet(set, SIGSTOP);
|
OsSigAddSet(set, SIGSTOP);
|
||||||
|
@ -529,7 +582,7 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
|
||||||
sigcb->sigwaitmask = NULL_SIGNAL_SET;
|
sigcb->sigwaitmask = NULL_SIGNAL_SET;
|
||||||
}
|
}
|
||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
(void) memcpy_s(info, sizeof(siginfo_t), &sigcb->sigunbinfo, sizeof(siginfo_t));
|
(VOID)memcpy_s(info, sizeof(siginfo_t), &sigcb->sigunbinfo, sizeof(siginfo_t));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -669,6 +722,7 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp)
|
||||||
sigcb->sigFlag |= process->sigShare;
|
sigcb->sigFlag |= process->sigShare;
|
||||||
UINT32 signo = (UINT32)FindFirstSetedBit(sigcb->sigFlag) + 1;
|
UINT32 signo = (UINT32)FindFirstSetedBit(sigcb->sigFlag) + 1;
|
||||||
UINT32 sigVal = (UINT32)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr);
|
UINT32 sigVal = (UINT32)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr);
|
||||||
|
OsMoveTmpInfoToUnbInfo(sigcb, signo);
|
||||||
OsProcessExitCodeSignalSet(process, signo);
|
OsProcessExitCodeSignalSet(process, signo);
|
||||||
sigcb->sigContext = sp;
|
sigcb->sigContext = sp;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue