X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=libmainloop%2Fsignal.c;fp=libmainloop%2Fsignal.c;h=fd37161b332689c7073b5065f930ab5e11549428;hp=877e3ec808665b5a5b7a44a8d928eafb5ebfcae7;hb=801e83f399c5307749d9a1caa7ca43814bf343a1;hpb=831140ef97f8ad74f97b65346da5c3b70924311b diff --git a/libmainloop/signal.c b/libmainloop/signal.c index 877e3ec..fd37161 100644 --- a/libmainloop/signal.c +++ b/libmainloop/signal.c @@ -36,6 +36,8 @@ static bool had_tmr=FALSE; WHook *mainloop_sigchld_hook=NULL; WHook *mainloop_sigusr2_hook=NULL; +static sigset_t special_sigs; + /*{{{ Timers */ @@ -79,44 +81,51 @@ int mainloop_gettime(struct timeval *val) #define USECS_IN_SEC 1000000 -static void do_timer_set() +bool libmainloop_get_timeout(struct timeval *tv) { - struct itimerval val={{0, 0}, {0, 0}}; - - if(queue==NULL){ - setitimer(ITIMER_REAL, &val, NULL); - return; - } + if(queue==NULL) + return FALSE; /* Subtract queue time from current time, don't go below zero */ - mainloop_gettime(&(val.it_value)); - if(TIMEVAL_LATER((queue)->when, val.it_value)){ - if(queue->when.tv_usecwhen, (*tv))){ + if(queue->when.tv_usectv_usec){ queue->when.tv_usec+=USECS_IN_SEC; queue->when.tv_sec--; } - val.it_value.tv_usec=queue->when.tv_usec-val.it_value.tv_usec; - val.it_value.tv_sec=queue->when.tv_sec-val.it_value.tv_sec; - if(val.it_value.tv_usec<0) - val.it_value.tv_usec=0; + tv->tv_usec=queue->when.tv_usec-tv->tv_usec; + tv->tv_sec=queue->when.tv_sec-tv->tv_sec; + if(tv->tv_usec<0) + tv->tv_usec=0; /* POSIX and some kernels have been designed by absolute morons and * contain idiotic artificial restrictions on the value of tv_usec, * that will only cause more code being run and clock cycles being * spent to do the same thing, as the kernel will in any case convert * the seconds to some other units. */ - val.it_value.tv_sec+=val.it_value.tv_usec/USECS_IN_SEC; - val.it_value.tv_usec%=USECS_IN_SEC; + tv->tv_sec+=tv->tv_usec/USECS_IN_SEC; + tv->tv_usec%=USECS_IN_SEC; }else{ had_tmr=TRUE; - return; + return FALSE; } + + return TRUE; +} + - val.it_interval.tv_usec=val.it_value.tv_usec; - val.it_interval.tv_sec=val.it_value.tv_sec; +static void do_timer_set() +{ + struct itimerval val={{0, 0}, {0, 0}}; - if((setitimer(ITIMER_REAL, &val, NULL))){ - had_tmr=TRUE; + if(libmainloop_get_timeout(&val.it_value)){ + val.it_interval.tv_usec=0; + val.it_interval.tv_sec=0; + + if((setitimer(ITIMER_REAL, &val, NULL))) + had_tmr=TRUE; + }else if(!had_tmr){ + setitimer(ITIMER_REAL, &val, NULL); } } @@ -250,6 +259,18 @@ bool mainloop_check_signals() } +void mainloop_block_signals(sigset_t *oldmask) +{ + sigprocmask(SIG_BLOCK, &special_sigs, oldmask); +} + + +bool mainloop_unhandled_signals() +{ + return (usr2_sig || wait_sig || kill_sig || had_tmr); +} + + static void add_to_current_time(struct timeval *when, uint msecs) { long tmp_usec; @@ -475,6 +496,7 @@ static void ignore_handler(int signal_num) #define FATAL(X) IFTRAP(X) signal(X, fatal_signal_handler); #define IGNORE(X) IFTRAP(X) signal(X, SIG_IGN) + void mainloop_trap_signals(const sigset_t *which) { struct sigaction sa; @@ -486,6 +508,7 @@ void mainloop_trap_signals(const sigset_t *which) which=&dummy; } + sigemptyset(&special_sigs); sigemptyset(&set); sigemptyset(&oldset); sigprocmask(SIG_SETMASK, &set, &oldset); @@ -509,24 +532,28 @@ void mainloop_trap_signals(const sigset_t *which) sa.sa_handler=timer_handler; sa.sa_flags=SA_RESTART; sigaction(SIGALRM, &sa, NULL); + sigaddset(&special_sigs, SIGALRM); } IFTRAP(SIGCHLD){ sa.sa_handler=chld_handler; sa.sa_flags=SA_NOCLDSTOP|SA_RESTART; sigaction(SIGCHLD, &sa, NULL); + sigaddset(&special_sigs, SIGCHLD); } IFTRAP(SIGUSR2){ sa.sa_handler=usr2_handler; sa.sa_flags=SA_RESTART; sigaction(SIGUSR2, &sa, NULL); + sigaddset(&special_sigs, SIGUSR2); } IFTRAP(SIGTERM){ sa.sa_handler=exit_handler; sa.sa_flags=SA_RESTART; sigaction(SIGTERM, &sa, NULL); + sigaddset(&special_sigs, SIGTERM); } IFTRAP(SIGUSR1){