diff options
author | rsc <devnull@localhost> | 2004-10-22 17:12:11 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-10-22 17:12:11 +0000 |
commit | aa200fe309dbb3292a218bcdf93615738963109a (patch) | |
tree | 79a3f77b73e76d3e8ed001c489c16a2ed6b24ebd /src | |
parent | 99834d136f84b9ddb216d9e20f22c608f87a3a39 (diff) | |
download | plan9port-aa200fe309dbb3292a218bcdf93615738963109a.tar.gz plan9port-aa200fe309dbb3292a218bcdf93615738963109a.tar.bz2 plan9port-aa200fe309dbb3292a218bcdf93615738963109a.zip |
try to avoid calling notify on the "dumb" signals
Diffstat (limited to 'src')
-rw-r--r-- | src/lib9/notify.c | 143 |
1 files changed, 91 insertions, 52 deletions
diff --git a/src/lib9/notify.c b/src/lib9/notify.c index 7f22e0fa..da075d71 100644 --- a/src/lib9/notify.c +++ b/src/lib9/notify.c @@ -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 }; @@ -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) @@ -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); +} + |