void ThrStop( int status ) { int mask ; SigAction( SIGTERM, SIG_IGN ) ; SigAction( SIGHUP, SIG_IGN ) ; mask = SigBlock() ; ThrRunningThread->priority = MAX_PRIORITY ; thrYield() ; SigUnBlock( mask ) ; /* OZ++ System Cleanup */ cleanup() ; /* Cleanup module with multithread */ ThrCleanupIO() ; /* Stop scheduler */ SigDisable() ; thrMain.aborted = status ; thrSwitch( &thrMain ) ; /* NOT REACH */ }
/*! \brief sigaction() for the specified thread. A \a threadID is < 0 specifies the current thread. */ int sigaction_etc(thread_id threadID, int signal, const struct sigaction *act, struct sigaction *oldAction) { struct thread *thread; cpu_status state; status_t error = B_OK; if (signal < 1 || signal > MAX_SIGNO || (SIGNAL_TO_MASK(signal) & ~BLOCKABLE_SIGNALS) != 0) return B_BAD_VALUE; state = disable_interrupts(); GRAB_THREAD_LOCK(); thread = (threadID < 0 ? thread_get_current_thread() : thread_get_thread_struct_locked(threadID)); if (thread) { if (oldAction) { // save previous sigaction structure memcpy(oldAction, &thread->sig_action[signal - 1], sizeof(struct sigaction)); } if (act) { T(SigAction(thread, signal, act)); // set new sigaction structure memcpy(&thread->sig_action[signal - 1], act, sizeof(struct sigaction)); thread->sig_action[signal - 1].sa_mask &= BLOCKABLE_SIGNALS; } if (act && act->sa_handler == SIG_IGN) { // remove pending signal if it should now be ignored atomic_and(&thread->sig_pending, ~SIGNAL_TO_MASK(signal)); } else if (act && act->sa_handler == SIG_DFL && (SIGNAL_TO_MASK(signal) & DEFAULT_IGNORE_SIGNALS) != 0) { // remove pending signal for those signals whose default // action is to ignore them atomic_and(&thread->sig_pending, ~SIGNAL_TO_MASK(signal)); } } else error = B_BAD_THREAD_ID; RELEASE_THREAD_LOCK(); restore_interrupts(state); return error; }
int OzOmWaitShutdownRequest() { int result = -3 ; SigAction( SIGTERM, nifHandlerSIGTERM ) ; OzExecEnterMonitor( &sd.lock ) ; if ( sd.flag < 0 ) { sd.flag = 0 ; while ( ! sd.flag ) OzExecWaitCondition( &sd.lock, &sd.cond ) ; result = 0 ; } else result = -1 ; OzExecExitMonitor( &sd.lock ) ; return( result ) ; }
int ThrStart( int tmax, int ticks ) { Thread t ; /* * Initialize scheduler module */ if ( (ThrPageSize = GETPAGESIZE()) <= 0 ) { ThrPanic( "GETPAGESIZE(): %m." ) ; } if ( (ThrDevZero = open( "/dev/zero", O_RDWR ) ) < 0 ) { ThrPanic( "open(/dev/zero): %m." ) ; } if ( tmax < 2 || THREAD_ID_MAX < tmax ) { ThrPanic( "ThrStart() : Invalid thread max = %d.", tmax ) ; } thrThreadTable = malloc( sizeof(ThreadRec) * tmax ) ; if ( thrThreadTable == NULL ) { ThrPanic( "ThrStart() Can't malloc Thread table[%d]: %m.", tmax ) ; } thrThreadTableBreak = thrThreadTable + tmax ; t = thrThreadTableBreak ; while ( thrThreadTable != t -- ) { t->tid = 0 ; t->next = thrFreeThreads ; thrFreeThreads = t ; } /* * Initialize other modules without multithread. */ StkInitialize() ; SigInitialize() ; BrkInitialize() ; /* * Startup multithread scheduler. */ SigAction( SIGALRM, thrHandlerSIGALRM ) ; SigAction( SIGSEGV, thrHandlerSIGSEGV ) ; SigAction( SIGBUS, thrHandlerSIGSEGV ) ; SigAction( SIGILL, thrHandlerSIGSEGV ) ; SigAction( SIGFPE, thrHandlerSIGSEGV ) ; SigAction( SIGTERM, thrHandlerSIGHUP ) ; SigAction( SIGHUP, thrHandlerSIGHUP ) ; /* Create idle thread (tid=0) */ ThrRunningThread = &thrMain ; thrMain.StdIn = 0 ; thrMain.StdOut = 1 ; thrMain.StdErr = 2 ; thrMain.status = READY ; thrMain.first = 0 ; thrIdleThread = ThrCreate( thrIdle, NULL, 0, 0, 0, 1, ticks ) ; /* Multithread scheduler start. */ sigBlocking = 0 ; thrSwitch( thrIdleThread ) ; /* * Cleanup multithread scheduler. */ SigAction( SIGALRM, SIG_IGN ) ; SigAction( SIGSEGV, SIG_DFL ) ; SigAction( SIGBUS, SIG_DFL ) ; SigAction( SIGILL, SIG_DFL ) ; SigAction( SIGFPE, SIG_DFL ) ; SigAction( SIGTERM, SIG_DFL ) ; SigAction( SIGHUP, SIG_DFL ) ; SigAction( SIGTRAP, SIG_DFL ) ; /* * Shutdown other modules without multithread. */ BrkShutdown() ; SigShutdown() ; StkShutdown() ; /* * Shutdown scheduler module */ close( ThrDevZero ) ; free( thrThreadTable ) ; return( thrMain.aborted ) ; }