Пример #1
0
/* 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;
}
Пример #2
0
/*
  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);
}
Пример #3
0
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;
        }
    }
}
Пример #4
0
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);
}
Пример #5
0
int main(int argc, char *argv[]){

    unblock_signal();
    read_input(argc, argv);

    pthread_t th;
    pthread_create(&th, NULL, build, NULL);

    start();

}
Пример #6
0
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;
}
Пример #7
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);
}
Пример #8
0
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();
}
Пример #9
0
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);
}
Пример #10
0
/*
  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;
}
Пример #11
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));
}
Пример #12
0
/*
 * 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;
}
Пример #13
0
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);
}
Пример #14
0
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;
}