ttry to avoid calling notify on the "dumb" signals - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit aa200fe309dbb3292a218bcdf93615738963109a
 (DIR) parent 99834d136f84b9ddb216d9e20f22c608f87a3a39
 (HTM) Author: rsc <devnull@localhost>
       Date:   Fri, 22 Oct 2004 17:12:11 +0000
       
       ttry to avoid calling notify on the "dumb" signals
       
       Diffstat:
         M src/lib9/notify.c                   |     143 ++++++++++++++++++++-----------
       
       1 file changed, 91 insertions(+), 52 deletions(-)
       ---
 (DIR) diff --git a/src/lib9/notify.c b/src/lib9/notify.c
       t@@ -8,35 +8,36 @@ extern char *_p9sigstr(int, char*);
        static struct {
                int sig;
                int restart;
       +        int dumb;
        } sigs[] = {
       -        SIGHUP, 0,
       -        SIGINT, 0,
       -        SIGQUIT, 0,
       -        SIGILL, 0,
       -        SIGTRAP, 0,
       +        SIGHUP, 0, 0,
       +        SIGINT, 0, 0,
       +        SIGQUIT, 0, 0,
       +        SIGILL, 0, 0,
       +        SIGTRAP, 0, 0,
        /*        SIGABRT,        */
        #ifdef SIGEMT
       -        SIGEMT, 0,
       +        SIGEMT, 0, 0,
        #endif
       -        SIGFPE, 0,
       -        SIGBUS, 0,
       +        SIGFPE, 0, 0,
       +        SIGBUS, 0, 0,
        /*        SIGSEGV,        */
       -        SIGCHLD, 1,
       -        SIGSYS, 0,
       -        SIGPIPE, 0,
       -        SIGALRM, 0,
       -        SIGTERM, 0,
       -        SIGTSTP, 1,
       -        SIGTTIN, 1,
       -        SIGTTOU, 1,
       -        SIGXCPU, 0,
       -        SIGXFSZ, 0,
       -        SIGVTALRM, 0,
       -        SIGUSR1, 0,
       -        SIGUSR2, 0,
       -        SIGWINCH, 1,
       +        SIGCHLD, 1, 1,
       +        SIGSYS, 0, 0,
       +        SIGPIPE, 0, 1,
       +        SIGALRM, 0, 0,
       +        SIGTERM, 0, 0,
       +        SIGTSTP, 1, 1,
       +        SIGTTIN, 1, 1,
       +        SIGTTOU, 1, 1,
       +        SIGXCPU, 0, 0,
       +        SIGXFSZ, 0, 0,
       +        SIGVTALRM, 0, 0,
       +        SIGUSR1, 0, 0,
       +        SIGUSR2, 0, 0,
       +        SIGWINCH, 1, 1,
        #ifdef SIGINFO
       -        SIGINFO, 0,
       +        SIGINFO, 0, 0,
        #endif
        };
        
       t@@ -56,6 +57,13 @@ getonejmp(void)
        
        Jmp *(*_notejmpbuf)(void) = getonejmp;
        static void (*notifyf)(void*, char*);
       +static int alldumb;
       +
       +static void
       +nop(int sig)
       +{
       +        USED(sig);
       +}
        
        static void
        notifysigf(int sig)
       t@@ -85,40 +93,71 @@ noted(int v)
                return 0;
        }
        
       -int
       -notify(void (*f)(void*, char*))
       +static void
       +handlesig(int s, int r, int skip)
        {
       -        int i;
                struct sigaction sa, osa;
        
       +        /*
       +         * If someone has already installed a handler,
       +         * It's probably some ld preload nonsense,
       +         * like pct (a SIGVTALRM-based profiler).
       +         * Leave it alone.
       +         */
       +        sigaction(s, nil, &osa);
       +        if(osa.sa_handler != SIG_DFL && osa.sa_handler != notifysigf && osa.sa_handler != nop)
       +                return;
       +
                memset(&sa, 0, sizeof sa);
       -        if(f == 0)
       +        if(skip)
       +                sa.sa_handler = nop;
       +        else if(notifyf == 0)
                        sa.sa_handler = SIG_DFL;
       -        else{
       -                notifyf = f;
       +        else
                        sa.sa_handler = notifysigf;
       -        }
       -        for(i=0; i<nelem(sigs); i++){
       -                /*
       -                 * If someone has already installed a handler,
       -                 * It's probably some ld preload nonsense,
       -                 * like pct (a SIGVTALRM-based profiler).
       -                 * Leave it alone.
       -                 */
       -                sigaction(sigs[i].sig, nil, &osa);
       -                if(osa.sa_handler != SIG_DFL)
       -                        continue;
       -                /*
       -                 * We assume that one jump buffer per thread
       -                 * is okay, which means that we can't deal with 
       -                 * signal handlers called during signal handlers.
       -                 */
       -                sigfillset(&sa.sa_mask);
       -                if(sigs[i].restart)
       -                        sa.sa_flags |= SA_RESTART;
       -                else
       -                        sa.sa_flags &= ~SA_RESTART;
       -                sigaction(sigs[i].sig, &sa, nil);
       -        }
       +
       +        /*
       +         * We assume that one jump buffer per thread
       +         * is okay, which means that we can't deal with 
       +         * signal handlers called during signal handlers.
       +         */
       +        sigfillset(&sa.sa_mask);
       +        if(r)
       +                sa.sa_flags |= SA_RESTART;
       +        else
       +                sa.sa_flags &= ~SA_RESTART;
       +        sigaction(s, &sa, nil);
       +}
       +
       +int
       +notify(void (*f)(void*, char*))
       +{
       +        int i;
       +
       +        notifyf = f;
       +        for(i=0; i<nelem(sigs); i++)
       +                handlesig(sigs[i].sig, sigs[i].restart, sigs[i].dumb && !alldumb);
                return 0;
        }
       +
       +void
       +notifyall(int all)
       +{
       +        int i;
       +
       +        alldumb = all;
       +        for(i=0; i<nelem(sigs); i++)
       +                if(sigs[i].dumb)
       +                        handlesig(sigs[i].sig, sigs[i].restart, !all);
       +}
       +
       +void
       +notifyatsig(int sig, int use)
       +{
       +        int i;
       +
       +        for(i=0; i<nelem(sigs); i++)
       +                if(sigs[i].sig == sig)
       +                        handlesig(sigs[i].sig, sigs[i].restart, 0);
       +}
       +