-#ifndef __i386__
- boolean were_in_lisp = !foreign_function_call_active;
-#endif
-
- SetSymbolValue(INTERRUPT_PENDING, NIL);
-
- if (maybe_gc_pending) {
- maybe_gc_pending = 0;
-#ifndef __i386__
- if (were_in_lisp)
-#endif
- {
- fake_foreign_function_call(context);
- }
- funcall0(SymbolFunction(MAYBE_GC));
-#ifndef __i386__
- if (were_in_lisp)
-#endif
- {
- undo_fake_foreign_function_call(context);
- }
- }
-
- /* FIXME: This isn't very clear. It would be good to reverse
- * engineer it and rewrite the code more clearly, or write a clear
- * explanation of what's going on in the comments, or both.
- *
- * WHN's question 1a: How come we unconditionally copy from
- * pending_mask into the context, and then test whether
- * pending_signal is set?
- *
- * WHN's question 1b: If pending_signal wasn't set, how could
- * pending_mask be valid?
- *
- * Dan Barlow's reply (sbcl-devel 2001-03-13): And the answer is -
- * or appears to be - because interrupt_maybe_gc set it that way
- * (look in the #ifndef __i386__ bit). We can't GC during a
- * pseudo-atomic, so we set maybe_gc_pending=1 and
- * arch_set_pseudo_atomic_interrupted(..) When we come out of
- * pseudo_atomic we're marked as interrupted, so we call
- * interrupt_handle_pending, which does the GC using the pending
- * context (it needs a context so that it has registers to use as
- * GC roots) then notices there's no actual interrupt handler to
- * call, so doesn't. That's the second question [1b] answered,
- * anyway. Why we still need to copy the pending_mask into the
- * context given that we're now done with the context anyway, I
- * couldn't say. */
- memcpy(os_context_sigmask_addr(context), &pending_mask, sizeof(sigset_t));
- sigemptyset(&pending_mask);
- if (pending_signal) {
- int signal = pending_signal;
- siginfo_t info;
- memcpy(&info, &pending_info, sizeof(siginfo_t));
- pending_signal = 0;
- interrupt_handle_now(signal, &info, context);
- }
+ struct thread *thread;
+ struct interrupt_data *data;
+
+ thread=arch_os_get_current_thread();
+ data=thread->interrupt_data;
+ /* FIXME I'm not altogether sure this is appropriate if we're
+ * here as the result of a pseudo-atomic */
+ SetSymbolValue(INTERRUPT_PENDING, NIL,thread);
+
+ /* restore the saved signal mask from the original signal (the
+ * one that interrupted us during the critical section) into the
+ * os_context for the signal we're currently in the handler for.
+ * This should ensure that when we return from the handler the
+ * blocked signals are unblocked */
+
+ memcpy(os_context_sigmask_addr(context), &data->pending_mask,
+ REAL_SIGSET_SIZE_BYTES);
+
+ sigemptyset(&data->pending_mask);
+ /* This will break on sparc linux: the deferred handler really wants
+ * to be called with a void_context */
+ run_deferred_handler(data,(void *)context);