?? signal.cxx
字號:
// 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 + -