⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 signal.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 3 页
字号:
    // the one supplied.    sigset_t old = self->sigmask;    self->sigmask = *set;    // Loop until a signal gets delivered    while( !cyg_deliver_signals() )        signal_sigwait.wait();    self->sigmask = old;        signal_mutex.unlock();        SIGNAL_RETURN(EINTR);}    // -------------------------------------------------------------------------// Wait for a signal in set to arrive// Implement this as a variant on sigtimedwait().externC int sigwait  (const sigset_t *set, int *sig){    SIGNAL_ENTRY();    siginfo_t info;        int ret = sigtimedwait( set, &info, NULL );    if( ret == -1 )        SIGNAL_RETURN(errno);    *sig = ret;        SIGNAL_RETURN(0);}// -------------------------------------------------------------------------// Do the same as sigwait() except return a siginfo_t object too.// Implement this as a variant on sigtimedwait().externC int sigwaitinfo  (const sigset_t *set, siginfo_t *info){    SIGNAL_ENTRY();    int ret = sigtimedwait( set, info, NULL );        SIGNAL_RETURN_VALUE(ret);}// -------------------------------------------------------------------------// Wait either for a signal in the given set to become pending, or// for the timeout to expire. If timeout is NULL, wait for ever.externC int sigtimedwait  (const sigset_t *set, siginfo_t *info,                           const struct timespec *timeout){    SIGNAL_ENTRY();    // check for cancellation first.    pthread_testcancel();    int err = 0;    cyg_tick_count ticks;    if( timeout == NULL ) ticks = 0;    else ticks = cyg_timespec_to_ticks( timeout ) +             Cyg_Clock::real_time_clock->current_value();    pthread_info *self = pthread_self_info();        signal_mutex.lock();    sigset_t todo;    // Wait for a signal in the set to become pending    while( (todo = (*set & (sig_pending | self->sigpending))) == 0 )    {        // If timeout is not NULL, do a timed wait on the        // sigwait condition variable. If it is NULL - wait        // until we are woken.        if( timeout )        {            if( ticks == 0 || !signal_sigwait.wait(ticks) )            {                // If the timeout is actually zero, or we have waited and                // timed out, then we must quit with an error.                err = EAGAIN;                break;            }        }        else {            if ( !signal_sigwait.wait() ) {                // check we weren't woken up forcibly (e.g. to be cancelled)                // if so, pretend it's an error                err = EAGAIN;                break;            }        }                // Special case check for SIGALRM since the fact SIGALRM is masked        // would have prevented it being set pending in the alarm handler.        check_sigalarm();        cyg_posix_timer_asr(self);    }    if( err == 0 )    {        // There is a signal in the set that is pending: deliver        // it. todo contains a mask of all the signals that could be        // delivered now, but we only want to deliver one of them.        int signo = 0;        // Select the lowest numbered signal from the todo mask        HAL_LSBIT_INDEX( signo, todo );        signal_state *ss = &sigstate[signo];        sigset_t sigbit = 1L<<signo;        if( (ss->sa.sa_flags & SA_SIGINFO) && (ss->pending != NULL) )        {            // If the SA_SIGINFO bit is set, then there            // will be a signal_info object queued on the            // pending field.            signal_info *si = ss->pending->next;            *info = si->si;            // Remove the head signal_info object from the            // circular list.             if( ss->pending == si )                ss->pending = NULL;            else                ss->pending->next = si->next;                            si->next = siginfo_next;            siginfo_next = si;                        }        else        {            // Not a queued signal, or there is no signal_info object            // on the pending queue: fill in info structure with            // default values.            info->si_signo           = signo;            info->si_code            = SI_USER;            info->si_value.sival_int = 0;        }        // Clear the bit from the pending masks. If the pending        // queue is not empty, leave the bits set, otherwise clear        // them.                if( ss->pending == NULL )        {            // Clear the bit in both masks regardless of which            // one it actually came from. This is cheaper than            // trying to find out.            sig_pending &= ~sigbit;            self->sigpending &= ~sigbit;        }        // all done    }        signal_mutex.unlock();    pthread_testcancel();    if (err)        SIGNAL_RETURN(err);    else        SIGNAL_RETURN_VALUE( info->si_signo );}//==========================================================================// alarm, pause and sleep// -------------------------------------------------------------------------// Generate SIGALRM after some number of secondsexternC unsigned int alarm( unsigned int seconds ){    int res = 0;    struct timespec tv;    cyg_tick_count trigger, interval;    SIGNAL_ENTRY();    signal_mutex.lock();    if( sigalrm_armed )    {        sigalrm_alarm.disable();        sigalrm_alarm.get_times( &trigger, &interval );        // Convert trigger time back to interval        trigger -= Cyg_Clock::real_time_clock->current_value();                cyg_ticks_to_timespec( trigger, &tv );        res = tv.tv_sec;                sigalrm_armed = false;    }    if( seconds != 0 )    {        // Here we know that the sigalrm_alarm is unarmed, set it up        // to trigger in the required number of seconds.        tv.tv_sec = seconds;        tv.tv_nsec = 0;        trigger = cyg_timespec_to_ticks( &tv );        // Convert trigger interval to absolute time        trigger += Cyg_Clock::real_time_clock->current_value();                sigalrm_alarm.initialize( trigger, 0 );        sigalrm_armed = true;    }        signal_mutex.unlock();    CYG_REPORT_RETVAL(res);        return res;}// -------------------------------------------------------------------------// Wait for a signal to be delivered.externC int pause( void ){    SIGNAL_ENTRY();    signal_mutex.lock();    // Check for any pending signals that can be delivered and    // if there are none, wait for a signal to be generated    if( !cyg_deliver_signals() )        signal_sigwait.wait();    // Now check again for some signals to deliver    cyg_deliver_signals();        signal_mutex.unlock();        SIGNAL_RETURN(EINTR);}//==========================================================================// Signal sets// -------------------------------------------------------------------------// Clear all signals from set.externC int sigemptyset  (sigset_t *set){    SIGNAL_ENTRY();    *set = 0;        SIGNAL_RETURN(0);}    // -------------------------------------------------------------------------// Set all signals in set.externC int sigfillset  (sigset_t *set){    SIGNAL_ENTRY();    *set = ~0;        SIGNAL_RETURN(0);}    // -------------------------------------------------------------------------// Add signo to set.externC int sigaddset  (sigset_t *set, int signo){    SIGNAL_ENTRY();    int err = 0;        if( !SIGNAL_VALID(signo) )        err = EINVAL;    else *set |= 1<<signo;        SIGNAL_RETURN(err);}    // -------------------------------------------------------------------------// Remove signo from set.externC int sigdelset  (sigset_t *set, int signo){    SIGNAL_ENTRY();    int err = 0;        if( !SIGNAL_VALID(signo) )        err = EINVAL;    else *set &= ~(1<<signo);        SIGNAL_RETURN(err);}    // -------------------------------------------------------------------------// Test whether signo is in setexternC int sigismember  (const sigset_t *set, int signo){    SIGNAL_ENTRY();    int ret = 0;        if( !SIGNAL_VALID(signo) )        SIGNAL_RETURN(EINVAL);    if( *set & (1<<signo) ) ret = 1;    CYG_REPORT_RETVAL( ret );    return ret;}//==========================================================================// ISO C compatibility functions// -------------------------------------------------------------------------// Installs a new signal handler for the specified signal, and returns// the old handlerexternC sa_sighandler_t signal(int sig, sa_sighandler_t handler){    SIGNAL_ENTRY();    int err;    sa_sighandler_t ret;    struct sigaction new_action;    struct sigaction old_action;    sigemptyset( &new_action.sa_mask );    new_action.sa_flags = 0;    new_action.sa_handler = handler;    err = sigaction( sig, &new_action, &old_action );    if( err < 0 )        ret = SIG_ERR;    else ret = old_action.sa_handler;        CYG_REPORT_RETVAL( ret );    return ret;    }// -------------------------------------------------------------------------// raise() - ISO C 7.7.2 ////// Raises the signal, which will cause the current signal handler for// that signal to be calledexternC int raise(int sig){    return kill( 0, sig );}// -------------------------------------------------------------------------// siglongjmp()// Restores signal mask and longjumps.__externC void siglongjmp( sigjmp_buf env, int val ){    CYG_REPORT_FUNCNAME( "siglongjmp" );    CYG_REPORT_FUNCARG2( "&env=%08x, val=%d", &env, val );    // ISO C says that if we are passed val == 0, then we change it to 1    if( val == 0 )        val = 1;    if( env[0].__savemask )        pthread_sigmask( SIG_SETMASK, &env[0].__sigsavemask, NULL );        HAL_REORDER_BARRIER(); // prevent any chance of optimisation re-ordering    hal_longjmp( env[0].__jmp_buf, val );    HAL_REORDER_BARRIER(); // prevent any chance of optimisation re-ordering#ifdef CYGDBG_USE_ASSERTS    CYG_ASSERT( 0, "siglongjmp should not have reached this point!" );#else    for (;;)        CYG_EMPTY_STATEMENT;#endif    }#endif // ifdef CYGPKG_POSIX_SIGNALS// -------------------------------------------------------------------------// EOF signal.cxx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -