📄 siglib.c
字号:
{ *(struct sigpend **)pSigPend = _pSigQueueFreeHead; _pSigQueueFreeHead = pSigPend; } } } windExit (); /* KERNEL EXIT */ } return (OK); }/********************************************************************************* sigprocmask - examine and/or change the signal mask (POSIX)** This routine allows the calling process to examine and/or change its* signal mask. If the value of <pSet> is not NULL, it points to a set of* signals to be used to change the currently blocked set.** The value of <how> indicates the manner in which the set is changed and* consists of one of the following, defined in signal.h:* .iP SIG_BLOCK 4* the resulting set is the union of the current set and the signal set* pointed to by <pSet>.* .iP SIG_UNBLOCK* the resulting set is the intersection of the current set and the complement* of the signal set pointed to by <pSet>.* .iP SIG_SETMASK* the resulting set is the signal set pointed to by <pSset>.** RETURNS: OK (0), or ERROR (-1) if <how> is invalid.** ERRNO: EINVAL** SEE ALSO: sigsetmask(), sigblock()*/int sigprocmask ( int how, /* how signal mask will be changed */ const sigset_t *pSet, /* location of new signal mask */ sigset_t *pOset /* location to store old signal mask */ ) { struct sigtcb *pSigTcb; if ((pSigTcb = sigTcbGet()) == NULL) return (ERROR); /* errno was set */ kernelState = TRUE; /* KERNEL ENTER */ if (pOset != NULL) *pOset = pSigTcb->sigt_blocked; if (pSet != NULL) switch (how) { case SIG_BLOCK: pSigTcb->sigt_blocked |= *pSet; windExit (); /* KERNEL EXIT */ return (OK); case SIG_UNBLOCK: pSigTcb->sigt_blocked &= ~*pSet; break; case SIG_SETMASK: pSigTcb->sigt_blocked = *pSet; break; default: windExit (); /* KERNEL EXIT */ errnoSet (EINVAL); return (ERROR); } /* * check to see if we opened up any pending signals and run them. * sigpendrun has the horrible symantic of doing a windExit if * successful. */ if (sigPendRun(pSigTcb) == FALSE) windExit (); /* KERNEL EXIT */ return (OK); }/********************************************************************************* sigpending - retrieve the set of pending signals blocked from delivery (POSIX)** This routine stores the set of signals that are blocked from delivery and* that are pending for the calling process in the space pointed to by* <pSet>.** RETURNS: OK (0), or ERROR (-1) if the signal TCB cannot* be allocated.** ERRNO: ENOMEM*/int sigpending ( sigset_t *pSet /* location to store pending signal set */ ) { struct sigtcb *pSigTcb; if ((pSigTcb = sigTcbGet ()) == NULL) return (ERROR); *pSet = pSigTcb->sigt_pending; return (OK); }/********************************************************************************* sigsuspend - suspend the task until delivery of a signal (POSIX)** This routine suspends the task until delivery of a signal. While* suspended, <pSet> is used as the set of masked signals.** NOTE: Since the sigsuspend() function suspends thread execution* indefinitely, there is no successful completion return value.** RETURNS: -1, always.** ERRNO: EINTR*/int sigsuspend ( const sigset_t *pSet /* signal mask while suspended */ ) { Q_HEAD qHead; sigset_t oldset; struct sigtcb *pSigTcb; int savtype; if ((pSigTcb = sigTcbGet ()) == NULL) return (ERROR); /* errno was set */#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_SIG (EVENT_SIGSUSPEND, 1, (int) *pSet, 0);#endif if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype); } kernelState = TRUE; /* KERNEL ENTER */ /* save old set */ oldset = pSigTcb->sigt_blocked; pSigTcb->sigt_blocked = *pSet; /* check for pending */ if (sigPendRun (pSigTcb) == TRUE) { sigprocmask (SIG_SETMASK, &oldset, NULL); if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } errnoSet (EINTR); return (ERROR); } /* * Put ourself to sleep until a signal comes in. */ qInit (&qHead, Q_FIFO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);#ifdef WV_INSTRUMENTATION /* windview - level 2 event logging */ EVT_TASK_1 (EVENT_OBJ_SIGSUSPEND, pSet); #endif if (windPendQPut (&qHead, WAIT_FOREVER) != OK) { windExit (); /* KERNEL EXIT */ if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } return (ERROR); } windExit (); /* KERNEL EXIT */ /* * Restore old mask set. */ sigprocmask(SIG_SETMASK, &oldset, NULL); if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } errnoSet (EINTR); return (ERROR); }/********************************************************************************* pause - suspend the task until delivery of a signal (POSIX)** This routine suspends the task until delivery of a signal.** NOTE: Since the pause() function suspends thread execution indefinitely,* there is no successful completion return value.** RETURNS: -1, always.** ERRNO: EINTR*/int pause (void) { Q_HEAD qHead; int savtype;#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_SIG (EVENT_PAUSE, 1, taskIdCurrent,0);#endif if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype); } /* * Put ourself to sleep until a signal comes in. */ qInit (&qHead, Q_FIFO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); kernelState = TRUE; /* KERNEL ENTER */#ifdef WV_INSTRUMENTATION /* windview - level 2 event logging */ EVT_TASK_1 (EVENT_OBJ_SIGPAUSE, taskIdCurrent); /* log event */#endif if (windPendQPut (&qHead, WAIT_FOREVER) != OK) { windExit (); /* KERNEL EXIT */ if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } return (ERROR); } windExit (); /* KERNEL EXIT */ if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } errnoSet (EINTR); return (ERROR); }/********************************************************************************* sigtimedwait - wait for a signal** The function sigtimedwait() selects the pending signal from the set* specified by <pSet>. If multiple signals in <pSet> are pending, it will* remove and return the lowest numbered one. If no signal in <pSet> is pending* at the* time of the call, the task will be suspend until one of the signals in <pSet>* become pending, it is interrupted by an unblocked caught signal, or* until the time interval specified by <pTimeout> has expired.* If <pTimeout> is NULL, then the timeout interval is forever.** If the <pInfo> argument is non-NULL, the selected signal number is* stored in the `si_signo' member, and the cause of the signal is* stored in the `si_code' member. If the signal is a queued signal,* the value is stored in the `si_value' member of <pInfo>; otherwise* the content of `si_value' is undefined.** The following values are defined in signal.h for `si_code':* .iP SI_USER* the signal was sent by the kill() function.* .iP SI_QUEUE* the signal was sent by the sigqueue() function.* .iP SI_TIMER* the signal was generated by the expiration of a timer set by timer_settime().* .iP SI_ASYNCIO* the signal was generated by the completion of an asynchronous I/O request.* .iP SI_MESGQ* the signal was generated by the arrival of a message on an empty message* queue.* .LP** The function sigtimedwait() provides a synchronous mechanism for tasks* to wait for asynchromously generated signals. A task should use* sigprocmask() to block any signals it wants to handle synchronously and* leave their signal handlers in the default state. The task can then* make repeated calls to sigtimedwait() to remove any signals that are* sent to it.** RETURNS: Upon successful completion (that is, one of the signals specified* by <pSet> is pending or is generated) sigtimedwait() will return the selected* signal number. Otherwise, a value of -1 is returned and `errno' is set to* indicate the error.** ERRNO* .iP EINTR* The wait was interrupted by an unblocked, caught signal.* .iP EAGAIN* No signal specified by <pSet> was delivered within the specified timeout* period.* .iP EINVAL* The <pTimeout> argument specified a `tv_nsec' value less than zero or greater* than or equal to 1000 million.** SEE ALSO: sigwait()*/int sigtimedwait ( const sigset_t *pSet, /* the signal mask while suspended */ struct siginfo *pInfo, /* return value */ const struct timespec *pTimeout ) { struct sigtcb *pSigTcb; struct sigwait waitinfo; struct siginfo info; int signo; int wait; int status; int savtype; if ((pSigTcb = sigTcbGet()) == NULL) return (ERROR); /* errno was set */ if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype); } if (pTimeout != 0) { int tickRate = sysClkRateGet(); if ((pTimeout->tv_nsec < 0) || (pTimeout->tv_nsec > 1000000000)) { errno = EINVAL; if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } return (ERROR); } wait = pTimeout->tv_sec * tickRate + pTimeout->tv_nsec / (1000000000 / tickRate); } else wait = WAIT_FOREVER; kernelState = TRUE; /* KERNEL ENTER */ if ((signo = sigPendGet(pSigTcb, pSet, &info)) > 0) { windExit (); /* KERNEL EXIT */ if (pInfo != NULL) *pInfo = info; if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } return (signo); } waitinfo.sigw_set = *pSet; qInit (&waitinfo.sigw_wait, Q_FIFO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); pSigTcb->sigt_wait = &waitinfo;#ifdef WV_INSTRUMENTATION /* windview - level 2 event logging */ EVT_TASK_1 (EVENT_OBJ_SIGWAIT, waitinfo.sigw_wait);#endif if (windPendQPut (&waitinfo.sigw_wait, wait) != OK) { windExit (); /* KERNEL EXIT */ if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } return (ERROR); } status = windExit (); /* KERNEL EXIT */ pSigTcb->sigt_wait = 0; if (status != 0) { if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } errnoSet ((status == RESTART) ? EINTR : EAGAIN); return (-1); } if (pInfo != NULL) *pInfo = waitinfo.sigw_info; if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } return (waitinfo.sigw_info.si_signo); }/********************************************************************************* sigwaitinfo - wait for real-time signals** The function sigwaitinfo() is equivalent to calling sigtimedwait() with* <pTimeout> equal to NULL. See that manual entry for more information.** RETURNS: Upon successful completion (that is, one of the signals specified* by <pSet> is pending or is generated) sigwaitinfo() returns the selected* signal number. Otherwise, a value of -1 is returned and `errno' is set to* indicate the error.** ERRNO* .iP EINTR* The wait was interrupted by an unblocked, caught signal.*/int sigwaitinfo ( const sigset_t *pSet, /* the signal mask while suspended */ struct siginfo *pInfo /* return value */ ) { return (sigtimedwait (pSet, pInfo, (struct timespec *)NULL)); }/********************************************************************************* sigwait - wait for a signal to be delivered (POSIX)*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -