From: Gabor Melis Date: Thu, 5 Jan 2006 14:13:14 +0000 (+0000) Subject: 0.9.8.12: X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=23c9f168359d3a651d3764ea95705ab953fe08ee;p=sbcl.git 0.9.8.12: * NetBSD has a different bug in SA_NODEFER, detect it (patch by Richard M Kreuter) --- diff --git a/NEWS b/NEWS index a152d46..2aa55db 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ changes in sbcl-0.9.9 relative to sbcl-0.9.8: callbacks). (thanks to Cyrus Harmon and Heiner Schwarte) * bug fix: allow non-simple string symbol names (reported by Paul Dietz) + * bug fix: interrupt handling on NetBSD (thanks to Richard M + Kreuter) * optimization: faster implementation of EQUAL * fixed segfaults on x86 FreeBSD 7-current (thanks to NIIMI Satoshi) diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 6a52053..eca23aa 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -1080,9 +1080,17 @@ interrupt_maybe_gc_int(int signal, siginfo_t *info, void *void_context) * the whole sa_mask is ignored and instead of not adding the signal * in question to the mask. That means if it's not blockable the * signal must be unblocked at the beginning of signal handlers. + * + * It turns out that NetBSD's SA_NODEFER doesn't DTRT in a different + * way: if SA_NODEFER is set and the signal is in sa_mask, the signal + * will be unblocked in the sigmask during the signal handler. -- RMK + * X-mas day, 2005 */ static volatile int sigaction_nodefer_works = -1; +#define SA_NODEFER_TEST_BLOCK_SIGNAL SIGABRT +#define SA_NODEFER_TEST_KILL_SIGNAL SIGUSR1 + static void sigaction_nodefer_test_handler(int signal, siginfo_t *info, void *void_context) { @@ -1090,8 +1098,14 @@ sigaction_nodefer_test_handler(int signal, siginfo_t *info, void *void_context) int i; sigemptyset(&empty); sigprocmask(SIG_BLOCK, &empty, ¤t); + /* There should be exactly two blocked signals: the two we added + * to sa_mask when setting up the handler. NetBSD doesn't block + * the signal we're handling when SA_NODEFER is set; Linux before + * 2.6.13 or so also doesn't block the other signal when + * SA_NODEFER is set. */ for(i = 1; i < NSIG; i++) - if (sigismember(¤t, i) != ((i == SIGABRT) ? 1 : 0)) { + if (sigismember(¤t, i) != + (((i == SA_NODEFER_TEST_BLOCK_SIGNAL) || (i == signal)) ? 1 : 0)) { FSHOW_SIGNAL((stderr, "SA_NODEFER doesn't work, signal %d\n", i)); sigaction_nodefer_works = 0; } @@ -1107,19 +1121,23 @@ see_if_sigaction_nodefer_works() sa.sa_flags = SA_SIGINFO | SA_NODEFER; sa.sa_sigaction = sigaction_nodefer_test_handler; sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGABRT); - sigaction(SIGUSR1, &sa, &old_sa); + sigaddset(&sa.sa_mask, SA_NODEFER_TEST_BLOCK_SIGNAL); + sigaddset(&sa.sa_mask, SA_NODEFER_TEST_KILL_SIGNAL); + sigaction(SA_NODEFER_TEST_KILL_SIGNAL, &sa, &old_sa); /* Make sure no signals are blocked. */ { sigset_t empty; sigemptyset(&empty); sigprocmask(SIG_SETMASK, &empty, 0); } - kill(getpid(), SIGUSR1); + kill(getpid(), SA_NODEFER_TEST_KILL_SIGNAL); while (sigaction_nodefer_works == -1); - sigaction(SIGUSR1, &old_sa, NULL); + sigaction(SA_NODEFER_TEST_KILL_SIGNAL, &old_sa, NULL); } +#undef SA_NODEFER_TEST_BLOCK_SIGNAL +#undef SA_NODEFER_TEST_KILL_SIGNAL + static void unblock_me_trampoline(int signal, siginfo_t *info, void *void_context) { diff --git a/version.lisp-expr b/version.lisp-expr index e6a68d3..d2f31b8 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.9.8.11" +"0.9.8.12"