-void run_deferred_handler(struct interrupt_data *data, void *v_context) ;
+void run_deferred_handler(struct interrupt_data *data, void *v_context);
static void store_signal_data_for_later (struct interrupt_data *data,
void *handler, int signal,
siginfo_t *info,
static sigset_t deferrable_sigset;
static sigset_t blockable_sigset;
-inline static void check_blockables_blocked_or_lose()
+void
+check_blockables_blocked_or_lose()
{
/* Get the current sigmask, by blocking the empty set. */
sigset_t empty,current;
lispobj info_sap,context_sap = alloc_sap(context);
info_sap = alloc_sap(info);
- /* Allow signals again. */
- thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
+ /* Leave deferrable signals blocked, the handler itself will
+ * allow signals again when it sees fit. */
+#ifdef LISP_FEATURE_SB_THREAD
+ {
+ sigset_t unblock;
+ sigaddset(&unblock, SIG_STOP_FOR_GC);
+ thread_sigmask(SIG_UNBLOCK, &unblock, 0);
+ }
+#endif
FSHOW_SIGNAL((stderr,"/calling Lisp-level handler\n"));
FSHOW_SIGNAL((stderr,"thread=%lu suspended\n",thread->os_thread));
sigemptyset(&ss); sigaddset(&ss,SIG_STOP_FOR_GC);
- sigwaitinfo(&ss,0);
+ /* It is possible to get SIGCONT (and probably other
+ * non-blockable signals) here. */
+ while (sigwaitinfo(&ss,0) != SIG_STOP_FOR_GC);
FSHOW_SIGNAL((stderr,"thread=%lu resumed\n",thread->os_thread));
if(thread->state!=STATE_RUNNING) {
lose("sig_stop_for_gc_handler: wrong thread state on wakeup: %ld\n",
void interrupt_thread_handler(int num, siginfo_t *info, void *v_context)
{
os_context_t *context = (os_context_t*)arch_os_get_context(&v_context);
+ /* let the handler enable interrupts again when it sees fit */
+ sigaddset_deferrable(os_context_sigmask_addr(context));
arrange_return_to_lisp_function(context, SymbolFunction(RUN_INTERRUPTION));
}