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

📄 signal.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 3 页
字号:
                // This is a standard signal delivery.                CYG_CHECK_FUNC_PTR( ss->sa.sa_handler,                                    "Bad sa_handler signal handler" );                ss->sa.sa_handler( signo );            }            // Relock the mutex             signal_mutex.lock();                            // Restore original signal mask            self->sigmask = oldmask;            // return that we have handled a signal            res = true;        }    }    if( !locked ) signal_mutex.unlock();        return res;}// -------------------------------------------------------------------------// Utility routine to signal any threads waiting in sigwait*().void cyg_posix_signal_sigwait(){    signal_sigwait.broadcast();}       // -------------------------------------------------------------------------// Action routine called from kernel alarm to deliver the SIGALRM signal.// We cannot call any signal delivery functions directly here, so we simply// set a flag and schedule an ASR to be called.static void sigalrm_action( Cyg_Alarm *alarm, CYG_ADDRWORD data ){    sigset_t mask;    sigalrm_armed = false;    sigalrm_pending = true;    sigemptyset( &mask );    sigaddset( &mask, SIGALRM );    // Wake up any threads in sigsuspend() and sigwait() in case they    // are waiting for an alarm, and would have SIGALRM masked    signal_sigwait.broadcast();        cyg_posix_pthread_release_thread( &mask );}// -------------------------------------------------------------------------// Check for SIGALRMs. This is called from the ASR and sigtimedwait()// as alarms need to be handled as a special case.static __inline__ void check_sigalarm(void){    // If there is a pending SIGALRM, generate it    if( sigalrm_pending )    {        sigalrm_pending = false;                struct sigevent sev;        sev.sigev_notify           = SIGEV_SIGNAL;        sev.sigev_signo            = SIGALRM;        sev.sigev_value.sival_int  = 0;        // generate the signal        cyg_sigqueue( &sev, SI_USER );    }}// -------------------------------------------------------------------------// signal ASR function. This is called from the general POSIX ASR to// deal with any signal related issues.externC void cyg_posix_signal_asr(pthread_info *self){    check_sigalarm();    // Now call cyg_deliver_signals() to see if we can    // handle any signals now.        cyg_deliver_signals();}//==========================================================================// Per-thread initialization and destructionexternC void cyg_posix_thread_siginit( pthread_info *thread,                                       pthread_info *parentthread ){    // Clear out signal masks    sigemptyset( &thread->sigpending );    // but threads inherit signal masks    if ( NULL == parentthread )        sigemptyset( &thread->sigmask );    else        thread->sigmask = parentthread->sigmask;        cyg_pthread_exception_init( thread );}externC void cyg_posix_thread_sigdestroy( pthread_info *thread ){    cyg_pthread_exception_destroy( thread );}//==========================================================================// Functions to generate signals// -------------------------------------------------------------------------// Deliver sig to a process.// eCos only supports the value 0 for pid.externC int kill (pid_t pid, int sig){    SIGNAL_ENTRY();    if( !SIGNAL_VALID(sig) )        SIGNAL_RETURN(EINVAL);        if( pid != 0 )        SIGNAL_RETURN(ESRCH);    struct sigevent sev;    sev.sigev_notify           = SIGEV_SIGNAL;    sev.sigev_signo            = sig;    sev.sigev_value.sival_int  = 0;        cyg_sigqueue( &sev, SI_USER );    cyg_deliver_signals();        SIGNAL_RETURN(0);}// -------------------------------------------------------------------------externC int pthread_kill (pthread_t threadid, int sig){    SIGNAL_ENTRY();    if( !SIGNAL_VALID(sig) )        SIGNAL_RETURN(EINVAL);        struct sigevent sev;    pthread_info *thread = pthread_info_id(threadid);    if( thread == NULL )        SIGNAL_RETURN(ESRCH);        sev.sigev_notify           = SIGEV_SIGNAL;    sev.sigev_signo            = sig;    sev.sigev_value.sival_int  = 0;        cyg_sigqueue( &sev, SI_USER, thread );    cyg_deliver_signals();        SIGNAL_RETURN(0);}//==========================================================================// Functions to catch signals// -------------------------------------------------------------------------// Install signal handler for sig.externC int sigaction  (int sig, const struct sigaction *act,                        struct sigaction *oact){    SIGNAL_ENTRY();    if( !SIGNAL_VALID(sig) )        SIGNAL_RETURN(EINVAL);        signal_state *ss = &sigstate[sig];        signal_mutex.lock();    if( oact != NULL )        *oact = ss->sa;    ss->sa = *act;    if( ss->sa.sa_handler == SIG_IGN )    {        // Setting the handler to SIG_IGN causes any pending        // signals to be discarded and any queued values to also        // be removed.        pthread_info *self = pthread_self_info();        sigset_t sigbit = 1<<sig;        if( (sig_pending | self->sigpending) & sigbit )        {            // This signal is pending, clear it            sig_pending &= ~sigbit;            self->sigpending &= ~sigbit;            // Clean out any queued signal_info objects            while( ss->pending != NULL )            {                signal_info *si = ss->pending->next;                                // Remove the head signal_info object from the                // circular list.                 if( ss->pending == si )                    ss->pending = NULL;                else                    ss->pending->next = si->next;                // Return it to the free list                si->next = siginfo_next;                siginfo_next = si;            }        }    }        cyg_deliver_signals();        signal_mutex.unlock();        SIGNAL_RETURN(0);}    // -------------------------------------------------------------------------// Queue signal to process with value.externC int sigqueue (pid_t pid, int sig, const union sigval value){    SIGNAL_ENTRY();    if( !SIGNAL_VALID(sig) )        SIGNAL_RETURN(EINVAL);        struct sigevent sev;    sev.sigev_notify   = SIGEV_SIGNAL;    sev.sigev_signo    = sig;    sev.sigev_value    = value;        cyg_sigqueue( &sev, SI_QUEUE );    cyg_deliver_signals();        SIGNAL_RETURN(0);}    //==========================================================================// Functions to deal with current blocked and pending masks// -------------------------------------------------------------------------// Set process blocked signal mask// Map this onto pthread_sigmask().externC int sigprocmask  (int how, const sigset_t *set, sigset_t *oset){    return pthread_sigmask( how, set, oset);}    // -------------------------------------------------------------------------// Set calling thread's blocked signal maskexternC int pthread_sigmask (int how, const sigset_t *set, sigset_t *oset){    int err = 0;        SIGNAL_ENTRY();    pthread_info *self = pthread_self_info();    // Save old set    if( oset != NULL )        *oset = self->sigmask;    if( set != NULL )    {        switch( how )        {        case SIG_BLOCK:            self->sigmask |= *set;            break;                case SIG_UNBLOCK:            self->sigmask &= ~*set;            break;                    case SIG_SETMASK:            self->sigmask = *set;            break;        default:            err = EINVAL;            break;        }    }    // Deliver any newly unblocked signals    cyg_deliver_signals();        SIGNAL_RETURN(err);}// -------------------------------------------------------------------------// Exported routine to set calling thread's blocked signal mask//// Optionally set and return the current thread's signal mask. This is// exported to other packages so that they can manipulate the signal// mask without necessarily having them delivered (as calling// pthread_sigmask() would). Signals can be delivered by calling// cyg_posix_deliver_signals().externC void cyg_pthread_sigmask_set (const sigset_t *set, sigset_t *oset){    pthread_info *self = pthread_self_info();    if( self != NULL )    {        if( oset != NULL )            *oset = self->sigmask;        if( set != NULL )            self->sigmask = *set;    }}// -------------------------------------------------------------------------// Exported routine to test for any pending signals.//// This routine tests for any pending undelivered, unmasked// signals. If there are any it returns true.  This is exported to// other packages, such as FILEIO, so that they can detect whether to// abort a current API call with an EINTR result.externC cyg_bool cyg_posix_sigpending(void){    pthread_info *self = pthread_self_info();    if( self == NULL )        return false;        return ( ((sig_pending | self->sigpending) & ~self->sigmask) != 0 );}// -------------------------------------------------------------------------// Exported routine to deliver selected signals//// This routine optionally sets the given mask and then tries to// deliver any pending signals that have been unmasked. This is// exported to other packages so that they can cause signals to be// delivered at controlled points during execution.externC void cyg_posix_deliver_signals( const sigset_t *mask ){    sigset_t oldmask;    pthread_info *self = pthread_self_info();    if( self != NULL )    {        if( mask != NULL )        {            oldmask = self->sigmask;            self->sigmask = *mask;        }        else            oldmask = 0;   // silence warning        cyg_deliver_signals();        if( mask != NULL )                    self->sigmask = oldmask;    }}// -------------------------------------------------------------------------// Get set of pending signals for this processexternC int sigpending  (sigset_t *set){    SIGNAL_ENTRY();    if( set == NULL )        SIGNAL_RETURN(EINVAL);        pthread_info *self = pthread_self_info();        *set = self->sigpending | sig_pending;        SIGNAL_RETURN(0);}    //==========================================================================// Wait for or accept signals// -------------------------------------------------------------------------// Block signals in set and wait for a signalexternC int sigsuspend  (const sigset_t *set){    SIGNAL_ENTRY();    pthread_info *self = pthread_self_info();    signal_mutex.lock();    // Save the old mask and set the current mask to

⌨️ 快捷键说明

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