1.0.25.24: x86/x86-64 runtime pseudo atomic fixes
[sbcl.git] / src / runtime / interrupt.c
index 88126e7..4860be2 100644 (file)
@@ -63,6 +63,7 @@
 #include "alloc.h"
 #include "dynbind.h"
 #include "interr.h"
+#include "pseudo-atomic.h"
 #include "genesis/fdefn.h"
 #include "genesis/simple-fun.h"
 #include "genesis/cons.h"
@@ -74,11 +75,21 @@ static void store_signal_data_for_later (struct interrupt_data *data,
                                          siginfo_t *info,
                                          os_context_t *context);
 
+static void
+fill_current_sigmask(sigset_t *sigset)
+{
+    /* Get the current sigmask, by blocking the empty set. */
+    sigset_t empty;
+    sigemptyset(&empty);
+    thread_sigmask(SIG_BLOCK, &empty, sigset);
+}
+
 void
 sigaddset_deferrable(sigset_t *s)
 {
     sigaddset(s, SIGHUP);
     sigaddset(s, SIGINT);
+    sigaddset(s, SIGTERM);
     sigaddset(s, SIGQUIT);
     sigaddset(s, SIGPIPE);
     sigaddset(s, SIGALRM);
@@ -122,6 +133,28 @@ sigset_t blockable_sigset;
 #endif
 
 void
+check_deferrables_blocked_in_sigset_or_lose(sigset_t *sigset)
+{
+#if !defined(LISP_FEATURE_WIN32)
+    int i;
+    for(i = 1; i < NSIG; i++) {
+        if (sigismember(&deferrable_sigset, i) && !sigismember(sigset, i))
+            lose("deferrable signal %d not blocked\n",i);
+    }
+#endif
+}
+
+void
+check_deferrables_blocked_or_lose(void)
+{
+#if !defined(LISP_FEATURE_WIN32)
+    sigset_t current;
+    fill_current_sigmask(&current);
+    check_deferrables_blocked_in_sigset_or_lose(&current);
+#endif
+}
+
+void
 check_blockables_blocked_or_lose(void)
 {
 #if !defined(LISP_FEATURE_WIN32)
@@ -406,14 +439,8 @@ interrupt_handle_pending(os_context_t *context)
 
     struct thread *thread;
 
-    /* Punt if in PA section, marking it as interrupted. This can
-     * happenat least if we pick up a GC request while in a
-     * WITHOUT-GCING with an outer PA -- it is not immediately clear
-     * to me that this should/could ever happen, but better safe then
-     * sorry. --NS 2007-05-15 */
     if (arch_pseudo_atomic_atomic(context)) {
-        arch_set_pseudo_atomic_interrupted(context);
-        return;
+        lose("Handling pending interrupt in pseduo atomic.");
     }
 
     thread = arch_os_get_current_thread();
@@ -1265,6 +1292,14 @@ install_handler(int signal, void handler(int, siginfo_t*, void*))
 #endif
 }
 
+/* This must not go through lisp as it's allowed anytime, even when on
+ * the altstack. */
+void
+sigabrt_handler(int signal, siginfo_t *info, void *void_context)
+{
+    lose("SIGABRT received.\n");
+}
+
 void
 interrupt_init(void)
 {
@@ -1287,7 +1322,7 @@ interrupt_init(void)
              * 3-argument form is expected.) */
             (void (*)(int, siginfo_t*, void*))SIG_DFL;
     }
-
+    undoably_install_low_level_interrupt_handler(SIGABRT, sigabrt_handler);
     SHOW("returning from interrupt_init()");
 #endif
 }