/* This function is reentrant */ static int handle_signal (Signal_Type *s) { int status = 0; int was_blocked; (void) block_signal (s->sig, &was_blocked); /* At this point, sig is blocked and the handler is about to be called. * The pending flag can be safely set to 0 here. */ s->pending = 0; if (s->handler != NULL) { int depth = SLstack_depth (); if ((-1 == SLang_start_arg_list ()) || (-1 == SLang_push_integer (s->sig)) || (-1 == SLang_end_arg_list ()) || (-1 == SLexecute_function (s->handler))) status = -1; if ((status == 0) && (depth != SLstack_depth ())) { SLang_verror (SL_Application_Error, "The signal handler %s corrupted the stack", s->handler->name); status = -1; } } if (was_blocked == 0) (void) unblock_signal (s->sig); return status; }
/* The gtthread_exit() function is analogous to pthread_exit. */ void gtthread_exit(void* retval) { int flag = 0, i = 0; //Node to be deleted steque_node_t* temp = q->front; void* exit_item = steque_front(q); block_signal(); //Setting the canceled flag and return value ((node_t*)exit_item) -> returns = retval; ((node_t*)exit_item) -> canceled = 1; //Check if this is the only executing thread. Exit. for (i = 0; (i < q->N); i++) { if(((node_t*)temp -> item) -> canceled == 0){ flag = 1 ; break; } temp = temp -> next; } if(flag == 0){ steque_destroy(q); exit(0); } unblock_signal(); raise(SIGVTALRM); }
void thread_kill() { sigset_t mask; ll* temp; ll* prev; while(thread_count != 0) { prev = temp = head; while(temp != NULL) { if(cur_thread == &temp->thr) { block_signal(&mask); if(temp == head) head = head->next; else prev->next = temp->next; thread_count--; printf("Thread %d with priority %d is exiting\n", cur_thread->id, cur_thread->prt); unblock_signal(&mask); } prev = temp; temp = temp->next; } } }
void clock_stop(void){ if (clock_state == TIMER_STOPPED) return; block_signal(SIGALRM); clock_state = TIMER_STOPPED; struct itimerval it_val = {{0,0},{0,0}}; setitimer(ITIMER_REAL,&it_val,NULL); unblock_signal(SIGALRM); }
int main(int argc, char *argv[]){ unblock_signal(); read_input(argc, argv); pthread_t th; pthread_create(&th, NULL, build, NULL); start(); }
NEINT32 wait_services() { #ifdef WIN32 NEINT32 ch; while( !ne_host_check_exit() ){ if(kbhit()) { ch = getch() ; if(NE_ESC==ch){ printf_dbg("you are hit ESC, program eixt\n") ; break ; } } else { ne_sleep(1000) ; } } #else #ifdef HANDLE_UNIX_SIGNAL while(!ne_host_check_exit() ){ if(-1==wait_signal_entry() ) { printf_dbg("exit from wait signal!\n") ; break ; } } unblock_signal() ; #else NEINT32 ch; #ifndef DEBUG_WITH_GDB installed_sig_handle(); #endif while( !ne_host_check_exit() ){ if(kbhit()) { ch = getch() ; if(NE_ESC==ch){ printf_dbg("you are hit ESC, program eixt\n") ; break ; } } else { ne_sleep(1000) ; } } #endif #endif return 0; }
void SIGINT_handler(int sig) { block_signal(sig); int i; pthread_t thread; // signal(sig, SIG_IGN); printf("From SIGINT: just got a %d (SIGUSR1) signal\n", sig); for(i=0;message_box->client[i]!=0;i++); printf("Creating Thread for - Client with PID %d, Index: %d\n",(int)message_box->client[i-1],i-1); // signal(sig, SIGINT_handler); pthread_create(&thread,NULL,server_thread,(void*) (i-1)); pthread_detach(thread); unblock_signal(sig); }
void alarm_handler(int sig) { void* current = (node_t*)malloc(sizeof(node_t)); void* next = (node_t*)malloc(sizeof(node_t)); block_signal(); current = steque_front(q); steque_cycle(q); while(1) { next = steque_front(q); if((((node_t*)next)->canceled) == 0){ break; } steque_cycle(q); } set_alarm(); swapcontext (((node_t*)current)->thread_ctx, ((node_t*)next)->thread_ctx); unblock_signal(); }
void commit_comes(int sessionfd, const char* msg, int RW){ long pageaddr = *(long*)msg; block_signal(SIGALRM); // printf(" invalidation responce at %lx\n", pageaddr); q_dta_t* the_queue = &req_queues[addr_to_pagenum (dsm_heaptop, pageaddr, dsm_pagesize)]; if (RW == QUEUE_WRITE){ memcpy((void*)pageaddr, msg + sizeof(long), dsm_pagesize); assert(the_queue->update_pending); if (the_queue->listlen){ if (the_queue->num_parallel_readers){ for (int i = 0;i < the_queue->num_parallel_readers;i++){ int posval = the_queue->fd_queue[(i + the_queue->currhead) % (2*NumNode)]; dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pageaddr,ABS(posval)); } }else{ dsm_send(0, dsm_pagesize, SERVER_PAGE, (char*)pageaddr, ABS(queue_top(the_queue))); } } } the_queue->update_pending = 0; unblock_signal(SIGALRM); }
/* The gtthread_cancel() function is analogous to pthread_cancel, allowing one thread to terminate another asynchronously. */ int gtthread_cancel(gtthread_t thread){ int i = 0; steque_node_t* current = q->front; block_signal(); if (gtthread_equal(thread, gtthread_self())){ gtthread_exit((void*)GTTHREAD_CANCELED); } for (i = 0; (i < q->N); i++) { if(gtthread_equal(thread, ((node_t*)current -> item) -> id)) { if (((node_t*)current -> item) -> canceled == 1){ return ESRCH; } else{ ((node_t*)current -> item) -> canceled = 1; ((node_t*)current -> item) -> returns = (void*)GTTHREAD_CANCELED; break; } } current = current -> next; } unblock_signal(); return 0; }
void HandleSyscalls() { register int cnt; fd_set readfds; int nfds = -1; time_t periodic_interval_len = 20; /* secs, empirically found :) */ nfds = (RSC_SOCK > CLIENT_LOG ) ? (RSC_SOCK + 1) : (CLIENT_LOG + 1); init_user_ids(Proc->owner, NULL); set_user_priv(); dprintf(D_FULLDEBUG, "HandleSyscalls: about to chdir(%s)\n", Proc->iwd); if( chdir(Proc->iwd) < 0 ) { sprintf( ErrBuf, "Can't chdir() to \"%s\"! [%s(%d)]", Proc->iwd, strerror(errno), errno ); HadErr = TRUE; return; } dprintf(D_SYSCALLS, "Shadow: Starting to field syscall requests\n"); errno = 0; time_t current_time = time(0); time_t next_periodic_update = current_time + periodic_interval_len; for(;;) { /* get a request and fulfill it */ FD_ZERO(&readfds); FD_SET(RSC_SOCK, &readfds); FD_SET(CLIENT_LOG, &readfds); struct timeval *ptimer = NULL, timer; timer.tv_sec = next_periodic_update - current_time; timer.tv_usec = 0; ptimer = &timer; /* if the current timer is set for a time longer than this, than truncate the timer required to the periodic limit. After inspection of the bandwidth timer, it seems that it will recorrect itself if select comes out of the loop before the timer goes off anyway to handle syscalls */ if ( timer.tv_sec > periodic_interval_len) { timer.tv_sec = next_periodic_update - current_time; ptimer = &timer; } unblock_signal(SIGCHLD); unblock_signal(SIGUSR1); #if defined(LINUX) || defined(Solaris) cnt = select(nfds, &readfds, (fd_set *)0, (fd_set *)0, ptimer); #else cnt = select(nfds, &readfds, 0, 0, ptimer); #endif block_signal(SIGCHLD); block_signal(SIGUSR1); if( cnt < 0 && errno != EINTR ) { EXCEPT("HandleSyscalls: select: errno=%d, rsc_sock=%d, client_log=%d",errno,RSC_SOCK,CLIENT_LOG); } if( cnt < 0 && errno == EINTR ) { continue; } if( FD_ISSET(CLIENT_LOG, &readfds) ) { if( HandleLog() < 0 ) { EXCEPT( "Peer went away" ); } } if( FD_ISSET(RSC_SOCK, &readfds) ) { if( do_REMOTE_syscall() < 0 ) { dprintf(D_SYSCALLS, "Shadow: do_REMOTE_syscall returned < 0\n"); break; } } if( FD_ISSET(UMBILICAL, &readfds) ) { dprintf(D_ALWAYS, "Shadow: Local scheduler apparently died, so I die too\n"); exit(1); } current_time = time(0); /* if this is true, then do the periodic_interval_len events */ if (current_time >= next_periodic_update) { next_periodic_update = current_time + periodic_interval_len; /* evaluate some attributes for policies like determining what to do if a job suspends wierdly or some such thing. This function has the possibility of making the shadow exit with JOB_SHOULD_HOLD or futzing up some global variables about how the job could've exited and letting Wraup take care of it. */ if (periodic_policy() == true) { break; } } #if defined(SYSCALL_DEBUG) strcpy( SyscallLabel, "shadow" ); #endif } /* The user job might exit while there is still unread data in the log. So, select with a timeout of zero, and flush everything from the log. */ /* NOTE: Since HandleLog does it's own loop to make sure it's read everything, we don't need a loop here, and should only call HandleLog once. In fact, if there's a problem w/ select(), a loop here can cause an infinite loop. -Derek Wright and Jim Basney, 2/17/99. */ HandleLog(); /* Take back normal condor privileges */ set_condor_priv(); /* If we are debugging with named pipes as our communications medium, won't have a condor_startd running - don't try to send to it. */ if( !UsePipes ) { send_quit( ExecutingHost, GlobalCap ); } dprintf(D_ALWAYS, "Shadow: Job %d.%d exited, termsig = %d, coredump = %d, retcode = %d\n", Proc->id.cluster, Proc->id.proc, WTERMSIG(JobStatus), WCOREDUMP(JobStatus), WEXITSTATUS(JobStatus)); }
/* * get_child_exit: This looks for dead child processes of the client. * There are two main sources of dead children: Either an /exec'd process * has exited, or the client has attempted to fork() off a helper process * (such as wserv or gzip) and that process has choked on itself. * * When SIGCHLD is recieved, the global variable 'dead_children_processes' * is incremented. When this function is called, we go through and call * waitpid() on all of the outstanding zombies, conditionally stopping when * we reach a specific wanted sub-process. * * If you want to stop reaping children when a specific subprocess is * reached, specify the process in 'wanted'. If all youre doing is cleaning * up after zombies and /exec's, then 'wanted' should be -1. */ int get_child_exit (pid_t wanted) { Process *proc; pid_t pid; int status, i; /* * Iterate until we've reaped all of the dead processes * or we've found the one asked for. */ if (dead_children_processes) { block_signal(SIGCHLD); while ((pid = waitpid(wanted, &status, WNOHANG)) > 0) { /* * First thing we do is look to see if the process we're * working on is the one that was asked for. If it is, * then we get its exit status information and return it. */ if (wanted != -1 && pid == wanted) { /* * We do not clear 'dead_children_processes' here * because we do not know if we've reaped all of * the children yet! Leaving it set means this * function is called again, and then if there are * no more left, it is cleared (below). */ unblock_signal(SIGCHLD); if (WIFEXITED(status)) return WEXITSTATUS(status); if (WIFSTOPPED(status)) return -(WSTOPSIG(status)); if (WIFSIGNALED(status)) return -(WTERMSIG(status)); } /* * If it wasnt the process asked for, then we've probably * stumbled across a dead /exec'd process. Look for the * corresponding child process, and mark it as being dead. */ else { for (i = 0; i < process_list_size; i++) { proc = process_list[i]; if (proc && proc->pid == pid) { proc->exited = 1; proc->termsig = WTERMSIG(status); proc->retcode = WEXITSTATUS(status); break; } } } } dead_children_processes = 0; unblock_signal(SIGCHLD); } /* * Now we may have reaped some /exec'd processes that were previously * dumb and have now exited. So we call cleanup_dead_processes() to * find and delete any such processes. */ cleanup_dead_processes(); /* * If 'wanted' is not -1, then we didnt find that process, and * if 'wanted' is -1, then you should ignore the retval anyhow. ;-) */ return -1; }
void queue_for_page(int sessionfd, long pagenum, int RW){ block_signal(SIGALRM); q_dta_t* the_queue = &(req_queues[pagenum]); assert(the_queue->num_parallel_readers <= the_queue->listlen); int make_active = 0; qaddr = pagenum_to_addr(dsm_heaptop, pagenum, dsm_pagesize); add_to_queue(RW*sessionfd, the_queue); if (RW == QUEUE_READ){ switch (the_queue->q_state){ case QUEUE_EMPTY: { int found; curr_owners[pagenum] = (short)(long)hash_get((void*)(long)sessionfd, sessionfd_to_nid,&found); assert(found); the_queue->q_state = QUEUE_READERS; if (!the_queue->update_pending){ long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize); dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd); } the_queue->num_parallel_readers = 1; break; } case QUEUE_WRITERS: { break; } case QUEUE_READERS: { if (!the_queue->update_pending){ long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize); dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd); } the_queue->num_parallel_readers++; break; } default:break; } }else{ the_queue->num_writers ++; switch (the_queue->q_state){ case QUEUE_EMPTY: { int found; curr_owners[pagenum] = (short)(long)hash_get((void*)(long)sessionfd, sessionfd_to_nid,&found); assert(found); the_queue->q_state = QUEUE_WRITERS; make_active = 1; if (!the_queue->update_pending){ long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize); dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd); } break; } case QUEUE_WRITERS: { break; } case QUEUE_READERS: { the_queue->q_state = QUEUE_WRITERS; make_active = 1; break; } default:break; } } if (make_active){ req_queues[pagenum].next_active = activehead; activehead = pagenum; clock_start(); } unblock_signal(SIGALRM); }
service_t::~service_t(void) { m_log->DEBUG("entered"); m_mutex.lock(); for (std::size_t sig = 0; sig < _NSIG; sig++) { struct sigaction act = {0}; switch (sig) { case SIGSEGV: case SIGILL: case SIGFPE: case SIGABRT: default: break; case SIGHUP: case SIGINT: case SIGQUIT: case SIGTRAP: case SIGUSR2: case SIGPIPE: case SIGALRM: case SIGCHLD: case SIGSTKFLT: case SIGUSR1: case SIGTERM: case SIGCONT: case SIGTSTP: case SIGTTIN: case SIGTTOU: case SIGURG: case SIGXCPU: case SIGXFSZ: case SIGVTALRM: case SIGPROF: case SIGWINCH: case SIGIO: case SIGPWR: case SIGUNUSED: act.sa_flags = SA_SIGINFO|SA_NOCLDWAIT|SA_ONSTACK; act.sa_sigaction = &service_t::shandler; if (0 > ::sigaction(sig, &act, nullptr)) m_log->ERROR("Failed to reset signal ", sig, " to SIG_DFL"); m_mutex.unlock(); unblock_signal(sig); m_mutex.lock(); break; } } if (-1 != m_urnd) { ::close(m_urnd); m_urnd = -1; } if (-1 != m_rnd) { ::close(m_rnd); m_rnd = -1; } m_log->INFO("deleting logging object"); delete m_log; m_log = nullptr; m_mutex.unlock(); return; }