diff --git a/configure.ac b/configure.ac index ea3ca614b..b039bb682 100644 --- a/configure.ac +++ b/configure.ac @@ -1311,7 +1311,7 @@ save_LIBS="$LIBS" LIBS="$BDW_GC_LIBS $LIBS" CFLAGS="$BDW_GC_CFLAGS $CFLAGS" -AC_CHECK_FUNCS([GC_do_blocking GC_call_with_gc_active GC_pthread_exit GC_pthread_cancel GC_allow_register_threads GC_pthread_sigmask GC_set_start_callback]) +AC_CHECK_FUNCS([GC_do_blocking GC_call_with_gc_active GC_pthread_exit GC_pthread_cancel GC_allow_register_threads GC_pthread_sigmask GC_set_start_callback GC_get_suspend_signal]) # Though the `GC_do_blocking ()' symbol is present in GC 7.1, it is not # declared, and has a different type (returning void instead of diff --git a/libguile/scmsigs.c b/libguile/scmsigs.c index 723d6a8c5..c324aaa0f 100644 --- a/libguile/scmsigs.c +++ b/libguile/scmsigs.c @@ -150,6 +150,26 @@ struct signal_pipe_data int err; }; +#ifndef HAVE_GC_GET_SUSPEND_SIGNAL +static int +GC_get_suspend_signal (void) +{ +#if defined SIG_SUSPEND + return SIG_SUSPEND; +#elif defined SIGPWR + return SIGPWR; +#elif defined SIGLOST + return SIGLOST; +#elif defined _SIGRTMIN + return _SIGRTMIN + 6; +#elif defined SIGRTMIN + return SIGRTMIN + 6; +#else +#error what suspend signal to use? +#endif +} +#endif /* HAVE_GC_GET_SUSPEND_SIGNAL */ + static void* read_signal_pipe_data (void * data) { @@ -168,6 +188,11 @@ signal_delivery_thread (void *data) #if HAVE_PTHREAD_SIGMASK /* not on mingw, see notes above */ sigset_t all_sigs; sigfillset (&all_sigs); + /* On libgc 7.1 and earlier, GC_do_blocking doesn't actually do + anything. So in that case, libgc will want to suspend the signal + delivery thread, so we need to allow it to do so by unmasking the + suspend signal. */ + sigdelset (&all_sigs, GC_get_suspend_signal ()); scm_i_pthread_sigmask (SIG_SETMASK, &all_sigs, NULL); #endif