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