/********************************************************************************************************* ** 函数名称: sigwaitinfo ** 功能描述: 等待 sigset 内信号的到来,以串行的方式从信号队列中取出信号进行处理, 信号将不再被执行. ** 输 入 : psigset 指定的信号集 ** psiginfo 获取的信号信息 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigwaitinfo (const sigset_t *psigset, struct siginfo *psiginfo) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; INT iSigNo; PLW_CLASS_SIGCONTEXT psigctx; struct siginfo siginfo; LW_CLASS_SIGWAIT sigwt; if (!psigset) { _ErrorHandle(EINVAL); return (PX_ERROR); } __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_D2(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_SIGWAIT, ptcbCur->TCB_ulId, *psigset, LW_NULL); __KERNEL_ENTER(); /* 进入内核 */ psigctx = _signalGetCtx(ptcbCur); iSigNo = _sigPendGet(psigctx, psigset, &siginfo); /* 检查当前是否有等待的信号 */ if (__issig(iSigNo)) { __KERNEL_EXIT(); /* 退出内核 */ if (psiginfo) { *psiginfo = siginfo; } return (siginfo.si_signo); } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL; /* 等待信号 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ sigwt.SIGWT_sigset = *psigset; psigctx->SIGCTX_sigwait = &sigwt; /* 保存等待信息 */ if (__KERNEL_EXIT()) { /* 是否其他信号激活 */ psigctx->SIGCTX_sigwait = LW_NULL; _ErrorHandle(EINTR); /* SA_RESTART 也退出 */ return (PX_ERROR); } psigctx->SIGCTX_sigwait = LW_NULL; if (psiginfo) { *psiginfo = sigwt.SIGWT_siginfo; } return (sigwt.SIGWT_siginfo.si_signo); }
/********************************************************************************************************* ** 函数名称: sigmask ** 功能描述: 通过信号的值获取一个信号掩码 ** 输 入 : iSigNo 信号 ** 输 出 : 信号掩码 ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigmask (INT iSigNo) { if (!__issig(iSigNo)) { _ErrorHandle(EINVAL); return (0); } return ((INT)__sigmask(iSigNo)); }
/********************************************************************************************************* ** 函数名称: sigdelset ** 功能描述: 从一个信号集中删除一个信号 ** 输 入 : psigset 信号集 ** iSigNo 信号 ** 输 出 : ERROR_NONE , EINVAL ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigdelset (sigset_t *psigset, INT iSigNo) { if (__issig(iSigNo)) { *psigset &= ~__sigmask(iSigNo); return (ERROR_NONE); } _ErrorHandle(EINVAL); return (PX_ERROR); }
/********************************************************************************************************* ** 函数名称: sigignore ** 功能描述: 将指定的信号设置为 SIG_IGN ** 输 入 : iSigNo 需要 SIG_IGN 的信号 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigignore (INT iSigNo) { if (!__issig(iSigNo)) { _ErrorHandle(EINVAL); return (PX_ERROR); } signal(iSigNo, SIG_IGN); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: sigismember ** 功能描述: 检查一个信号是否属于一个信号集 ** 输 入 : ** psigset 信号集 ** iSigNo 信号 ** 输 出 : 0 or 1 or -1 ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigismember (const sigset_t *psigset, INT iSigNo) { if (__issig(iSigNo)) { if (*psigset & __sigmask(iSigNo)) { return (1); } else { return (0); } } _ErrorHandle(EINVAL); return (PX_ERROR); }
/********************************************************************************************************* ** 函数名称: sighold ** 功能描述: 将新的需要阻塞的信号添加到当前线程 ** 输 入 : iSigNo 需要阻塞的信号 ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sighold (INT iSigNo) { sigset_t sigset = 0; if (!__issig(iSigNo)) { _ErrorHandle(EINVAL); return (PX_ERROR); } sigset = __sigmask(iSigNo); return (sigprocmask(SIG_BLOCK, &sigset, LW_NULL)); }
/********************************************************************************************************* ** 函数名称: sigqueue ** 功能描述: 发送队列类型信号, 如果是进程, 将发送给其主线程. ** 输 入 : ulId 线程 id 或者 进程号 ** iSigNo 信号 ** sigvalue 信号 value ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigqueue (LW_OBJECT_HANDLE ulId, INT iSigNo, const union sigval sigvalue) { REGISTER UINT16 usIndex; REGISTER PLW_CLASS_TCB ptcb; LW_SEND_VAL sendval; #if LW_CFG_MODULELOADER_EN > 0 if (ulId < LW_CFG_MAX_THREADS) { /* 进程号 */ ulId = vprocMainThread((pid_t)ulId); } #endif /* LW_CFG_MODULELOADER_EN > 0 */ usIndex = _ObjectGetIndex(ulId); if (!_ObjectClassOK(ulId, _OBJECT_THREAD)) { /* 检查 ID 类型有效性 */ _ErrorHandle(ESRCH); return (PX_ERROR); } if (_Thread_Index_Invalid(usIndex)) { /* 检查线程有效性 */ _ErrorHandle(ESRCH); return (PX_ERROR); } if (!__issig(iSigNo)) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (LW_CPU_GET_CUR_NESTING() || (ulId == API_ThreadIdSelf())) { _excJobAdd((VOIDFUNCPTR)sigqueue, (PVOID)ulId, (PVOID)iSigNo, (PVOID)sigvalue.sival_ptr, 0, 0, 0); return (ERROR_NONE); } #if LW_CFG_SMP_EN > 0 if (LW_NCPUS > 1) { /* 正工作在 SMP 多核模式 */ if (API_ThreadStop(ulId)) { return (PX_ERROR); } } #endif /* LW_CFG_SMP_EN */ __KERNEL_ENTER(); /* 进入内核 */ if (_Thread_Invalid(usIndex)) { __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ESRCH); return (PX_ERROR); } ptcb = __GET_TCB_FROM_INDEX(usIndex); if (ptcb->TCB_iDeleteProcStatus) { __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(ERROR_THREAD_OTHER_DELETE); return (PX_ERROR); } sendval = _doSigQueue(ptcb, iSigNo, sigvalue); #if LW_CFG_SMP_EN > 0 if (LW_NCPUS > 1) { /* 正工作在 SMP 多核模式 */ _ThreadContinue(ptcb, LW_FALSE); /* 在内核状态下唤醒被停止线程 */ } #endif /* LW_CFG_SMP_EN */ __KERNEL_EXIT(); /* 退出内核 */ #if LW_CFG_SIGNALFD_EN > 0 if (sendval == SEND_BLOCK) { _sigfdReadUnblock(ulId, iSigNo); } #endif /* LW_CFG_SIGNALFD_EN > 0 */ return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: sigaction ** 功能描述: 设置一个指定信号的服务向量, 同时可获取原始服务向量. ** (由于与 struct sigaction 重名, 所以这里直接使用 sigaction 函数名) ** 输 入 : iSigNo 信号 ** psigactionNew 新的处理结构 ** psigactionOld 先早的处理结构 ** 输 出 : ERROR_NONE , EINVAL ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigaction (INT iSigNo, const struct sigaction *psigactionNew, struct sigaction *psigactionOld) { struct sigaction *psigaction; PLW_CLASS_SIGCONTEXT psigctx; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_SIGPEND psigpend; REGISTER INT iSigIndex = __sigindex(iSigNo); /* TCB_sigaction 下标 */ if (!__issig(iSigNo)) { _ErrorHandle(EINVAL); return (PX_ERROR); } if ((iSigNo == SIGKILL) || (iSigNo == SIGSTOP)) { /* 不能捕获和忽略 */ _ErrorHandle(EINVAL); return (PX_ERROR); } LW_TCB_GET_CUR_SAFE(ptcbCur); psigctx = _signalGetCtx(ptcbCur); psigaction = &psigctx->SIGCTX_sigaction[iSigIndex]; if (psigactionOld) { *psigactionOld = *psigaction; /* 保存先早信息 */ } if (psigactionNew == LW_NULL) { return (ERROR_NONE); } __KERNEL_ENTER(); *psigaction = *psigactionNew; /* 拷贝新的处理控制块 */ psigaction->sa_mask &= ~__SIGNO_UNMASK; /* 有些信号不可屏蔽 */ __KERNEL_EXIT(); if (psigaction->sa_handler == SIG_IGN) { /* 设置为忽略该信号 */ __KERNEL_ENTER(); /* 进入内核 */ psigctx->SIGCTX_sigsetPending &= ~__sigmask(iSigNo); /* 没有等待 unmask 后执行的信号*/ psigctx->SIGCTX_sigsetKill &= ~__sigmask(iSigNo); /* 没有在屏蔽状态 kill 这个信号*/ { /* 删除队列中的相关信号节点 */ PLW_LIST_RING pringHead = psigctx->SIGCTX_pringSigQ[iSigIndex]; REGISTER PLW_LIST_RING pringSigP = pringHead; if (pringHead) { /* 唤醒队列中存在节点 */ do { psigpend = _LIST_ENTRY(pringSigP, LW_CLASS_SIGPEND, SIGPEND_ringSigQ); /* 获得 sigpend 控制块地址 */ pringSigP = _list_ring_get_next(pringSigP); /* 下一个节点 */ if ((psigpend->SIGPEND_siginfo.si_code != SI_KILL) && (psigpend->SIGPEND_iNotify == SIGEV_SIGNAL)) { _sigPendFree(psigpend); /* 需要交换空闲队列 */ } } while (pringSigP != pringHead); } } __KERNEL_EXIT(); /* 退出内核 */ } return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: sigtimedwait ** 功能描述: 等待 sigset 内信号的到来,以串行的方式从信号队列中取出信号进行处理, 信号将不再被执行. ** 输 入 : psigset 指定的信号集 ** psiginfo 获取的信号信息 ** ptv 超时时间 (NULL 表示一直等待) ** 输 出 : ERROR ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT sigtimedwait (const sigset_t *psigset, struct siginfo *psiginfo, const struct timespec *ptv) { INTREG iregInterLevel; PLW_CLASS_TCB ptcbCur; REGISTER PLW_CLASS_PCB ppcb; INT iSigNo; PLW_CLASS_SIGCONTEXT psigctx; struct siginfo siginfo; LW_CLASS_SIGWAIT sigwt; ULONG ulTimeout; if (!psigset) { _ErrorHandle(EINVAL); return (PX_ERROR); } if (ptv == LW_NULL) { /* 永久等待 */ ulTimeout = LW_OPTION_WAIT_INFINITE; } else { ulTimeout = __timespecToTick(ptv); } __THREAD_CANCEL_POINT(); /* 测试取消点 */ LW_TCB_GET_CUR_SAFE(ptcbCur); /* 当前任务控制块 */ MONITOR_EVT_D2(MONITOR_EVENT_ID_SIGNAL, MONITOR_EVENT_SIGNAL_SIGWAIT, ptcbCur->TCB_ulId, *psigset, LW_NULL); __KERNEL_ENTER(); /* 进入内核 */ psigctx = _signalGetCtx(ptcbCur); iSigNo = _sigPendGet(psigctx, psigset, &siginfo); /* 检查当前是否有等待的信号 */ if (__issig(iSigNo)) { __KERNEL_EXIT(); /* 退出内核 */ if (psiginfo) { *psiginfo = siginfo; } return (siginfo.si_signo); } if (ulTimeout == LW_OPTION_NOT_WAIT) { /* 不进行等待 */ __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(EAGAIN); return (PX_ERROR); } iregInterLevel = KN_INT_DISABLE(); /* 关闭中断 */ ptcbCur->TCB_usStatus |= LW_THREAD_STATUS_SIGNAL; /* 等待信号 */ ptcbCur->TCB_ucWaitTimeout = LW_WAIT_TIME_CLEAR; /* 清空等待时间 */ ppcb = _GetPcb(ptcbCur); __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */ if (ulTimeout != LW_OPTION_WAIT_INFINITE) { ptcbCur->TCB_ulDelay = ulTimeout; /* 设置超时时间 */ __ADD_TO_WAKEUP_LINE(ptcbCur); /* 加入等待扫描链 */ } else { ptcbCur->TCB_ulDelay = 0ul; } KN_INT_ENABLE(iregInterLevel); /* 打开中断 */ sigwt.SIGWT_sigset = *psigset; psigctx->SIGCTX_sigwait = &sigwt; /* 保存等待信息 */ if (__KERNEL_EXIT()) { /* 是否其他信号激活 */ psigctx->SIGCTX_sigwait = LW_NULL; _ErrorHandle(EINTR); /* SA_RESTART 也退出 */ return (PX_ERROR); } __KERNEL_ENTER(); /* 进入内核 */ if (ptcbCur->TCB_ucWaitTimeout == LW_WAIT_TIME_OUT) { /* 等待超时 */ __KERNEL_EXIT(); /* 退出内核 */ _ErrorHandle(EAGAIN); return (PX_ERROR); } __KERNEL_EXIT(); /* 退出内核 */ psigctx->SIGCTX_sigwait = LW_NULL; if (psiginfo) { *psiginfo = sigwt.SIGWT_siginfo; } return (sigwt.SIGWT_siginfo.si_signo); }
/********************************************************************************************************* ** 函数名称: lio_listio ** 功能描述: 同时发起多个传输 mode 参数可以是 LIO_WAIT 或 LIO_NOWAIT。LIO_WAIT 会阻塞这个调用, 直到所有的 I/O 都完成为止. 在操作进行排队之后,LIO_NOWAIT 就会返回. sigevent 引用定义了在所有 I/O 操作都完成时产生信号的方法。 ** 输 入 : mode LIO_WAIT or LIO_NOWAIT。LIO_WAIT ** list aio 请求控制块数组 (如果其中有 NULL, 程序将忽略) ** nent 数组元素个数 ** sig 所有 I/O 操作都完成时产生信号的方法 LIO_WAIT 将会忽略此参数! ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API int lio_listio (int mode, struct aiocb * const list[], int nent, struct sigevent *sig) { AIO_WAIT_CHAIN *paiowc; struct aiowait *paiowait; int iWait = 0; /* paiowait 下标 */ int iCnt; /* list 下标 */ int iRet = ERROR_NONE; #ifdef __SYLIXOS_KERNEL if (__PROC_GET_PID_CUR() != 0) { /* 需要使用外部库提供的 aio */ errno = ENOSYS; return (PX_ERROR); } #endif /* __SYLIXOS_KERNEL */ if ((mode != LIO_WAIT) && (mode != LIO_NOWAIT)) { errno = EINVAL; return (PX_ERROR); } if ((nent <= 0) || (list == LW_NULL)) { errno = EINVAL; return (PX_ERROR); } if (mode == LIO_WAIT) { paiowc = __aioCreateWaitChain(nent, LW_TRUE); /* 创建等待队列 */ } else { paiowc = __aioCreateWaitChain(nent, LW_FALSE); } if (paiowc == LW_NULL) { errno = ENOMEM; /* should be EAGAIN ? */ return (PX_ERROR); } if (sig) { paiowc->aiowc_sigevent = *sig; } else { paiowc->aiowc_sigevent.sigev_signo = 0; /* 无效信号不投递 */ } paiowait = paiowc->aiowc_paiowait; API_SemaphoreMPend(_G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE); for (iCnt = 0; iCnt < nent; iCnt++) { if (list[iCnt]) { if ((list[iCnt]->aio_lio_opcode != LIO_NOP) && (list[iCnt]->aio_req.aioreq_error != EINPROGRESS)) { list[iCnt]->aio_sigevent.sigev_notify = SIGEV_NONE; /* 不使用 aiocb 的 sigevent */ list[iCnt]->aio_req.aioreq_thread = API_ThreadIdSelf(); if (mode == LIO_WAIT) { paiowait[iWait].aiowt_pcond = &paiowc->aiowc_cond; paiowait[iWait].aiowt_pcnt = LW_NULL; paiowait[iWait].aiowt_psigevent = LW_NULL; paiowait[iWait].aiowt_paiowc = LW_NULL; /* 不需要代理线程释放 */ } else { paiowait[iWait].aiowt_pcond = LW_NULL; paiowait[iWait].aiowt_pcnt = LW_NULL; paiowait[iWait].aiowt_psigevent = &paiowc->aiowc_sigevent; paiowait[iWait].aiowt_paiowc = (void *)paiowc; } __aioAttachWaitNoCheck(list[iCnt], &paiowait[iWait]); /* aiocb and aiowait attach */ if (__aioEnqueue(list[iCnt]) == ERROR_NONE) { _List_Line_Add_Tail(&paiowait[iWait].aiowt_line, &paiowc->aiowc_pline); /* 加入 wait 链表 */ iWait++; } else { __aioDetachWait(LW_NULL, &paiowait[iWait]); /* 删除关联关系 */ iRet = PX_ERROR; } } } } if (iWait == 0) { /* 没有一个节点加入队列 */ __aioDeleteWaitChain(paiowc); API_SemaphoreMPost(_G_aioqueue.aioq_mutex); if (mode == LIO_NOWAIT) { if (sig && __issig(sig->sigev_signo)) { _doSigEvent(API_ThreadIdSelf(), sig, SI_ASYNCIO); } } return (ERROR_NONE); } else if (mode == LIO_WAIT) { /* 需要等待 */ __aioWaitChainSetCnt(paiowc, &iWait); /* 设置计数变量 */ while (iWait > 0) { if (API_ThreadCondWait(&paiowc->aiowc_cond, _G_aioqueue.aioq_mutex, LW_OPTION_WAIT_INFINITE)) { /* 等待所有请求执行完毕 */ break; } } __aioDeleteWaitChain(paiowc); /* 清除 wait 队列 */ } else { /* LIO_NOWAIT */ paiowc->aiowc_icnt = iWait; /* 必须使用全局变量 */ __aioWaitChainSetCnt(paiowc, &paiowc->aiowc_icnt); /* 设置计数变量 */ } API_SemaphoreMPost(_G_aioqueue.aioq_mutex); return (iRet); }