/* Configures the program to die with SIGALRM 'secs' seconds from now, if * 'secs' is nonzero, or disables the feature if 'secs' is zero. */ void time_alarm(unsigned int secs) { sigset_t oldsigs; time_init(); block_sigalrm(&oldsigs); deadline = secs ? time_add(time_now(), secs) : TIME_MIN; unblock_sigalrm(&oldsigs); }
int _sock_sig_setup (void) { volatile int sig; if (signal_depth > 0) return (0); if (++signal_depth > 1) return (0); _sock_start_timer(); wat_brkmode = wathndlcbrk; wathndlcbrk = 0; watcbroke = 0; sigalrm_caught = sigbrk_caught = 0; sigint_caught = sigquit_caught = 0; old_sigint = signal (SIGINT, sig_catch); #if defined(SIGQUIT) old_sigquit = signal (SIGQUIT, sig_catch); #endif #if defined(SIGBREAK) old_sigbrk = signal (SIGBREAK, sig_catch); #endif #if defined(SIGPIPE) old_sigpipe = signal (SIGPIPE, sig_catch); #endif #if defined(SIGALRM) && TRAP_SIGALRM old_sigalrm = signal (SIGALRM, sig_catch); block_sigalrm(); #endif sig = setjmp (sig_jmp); if (sig == 0) return (0); /* We'll get here only when sig_catch() calls longjmp() */ SOCK_DEBUGF ((NULL, ", interrupted by %s\n", sig_name(sig))); _sock_sig_restore(); return (-1); }
/* Like poll(), except: * * - On error, returns a negative error code (instead of setting errno). * * - If interrupted by a signal, retries automatically until the original * 'timeout' expires. (Because of this property, this function will * never return -EINTR.) * * - As a side effect, refreshes the current time (like time_refresh()). */ int time_poll(struct pollfd *pollfds, int n_pollfds, int timeout) { long long int start; sigset_t oldsigs; bool blocked; int retval; time_refresh(); start = time_msec(); blocked = false; for (;;) { int time_left; if (timeout > 0) { long long int elapsed = time_msec() - start; time_left = timeout >= elapsed ? timeout - elapsed : 0; } else { time_left = timeout; } retval = poll(pollfds, n_pollfds, time_left); if (retval < 0) { retval = -errno; } if (retval != -EINTR) { break; } if (!blocked && deadline == TIME_MIN) { block_sigalrm(&oldsigs); blocked = true; } time_refresh(); } if (blocked) { unblock_sigalrm(&oldsigs); } return retval; }
static int start_worker_thread( WORKER_FUNC_PTR _worker_main, BOINC_OPTIONS& options ) { worker_main = _worker_main; #ifdef _WIN32 // Create the event object used to signal between the // worker and event threads hQuitEvent = CreateEvent( NULL, // no security attributes TRUE, // manual reset event TRUE, // initial state is signaled NULL // object not named ); DWORD threadId; // Create and start worker thread // worker_thread_handle = CreateThread( NULL, 0, foobar, 0, CREATE_SUSPENDED, &threadId ); ResumeThread(worker_thread_handle); #else pthread_attr_t worker_thread_attr; sched_param param; int retval, currentpolicy, minpriority; // make the worker thread low priority // (current thread, i.e. graphics thread, should remain high priority) // retval = pthread_attr_init(&worker_thread_attr); if (retval) return ERR_THREAD; retval = pthread_attr_getschedparam(&worker_thread_attr, ¶m); if (retval) return ERR_THREAD; // Note: this sets the scheduling policy for the worker thread to // be the same as the scheduling policy of the main thread. // This may not be a wise choice. // retval = pthread_attr_getschedpolicy(&worker_thread_attr, ¤tpolicy); if (retval) return ERR_THREAD; minpriority = sched_get_priority_min(currentpolicy); if (minpriority == -1) return ERR_THREAD; param.sched_priority = minpriority; retval = pthread_attr_setschedparam(&worker_thread_attr, ¶m); if (retval) return ERR_THREAD; // initialize ID of calling thread (the graphics-thread!) graphics_thread = pthread_self(); // set worker stack size if specified // if (options.worker_thread_stack_size) { pthread_attr_setstacksize( &worker_thread_attr, options.worker_thread_stack_size ); } retval = pthread_create(&worker_thread, &worker_thread_attr, foobar, 0); if (retval) return ERR_THREAD; pthread_attr_destroy( &worker_thread_attr ); block_sigalrm(); #endif return 0; }