X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgc-common.c;h=11b3addeb48bab77441993fe34fd5e9e1506e608;hb=2e47ed527bdcb76cf5eb52f66cc08f4fb0a0041d;hp=4182448240756fbd9bd2c5663458cccabe1da961;hpb=3be1ab042ab74e008e40626cc6bd5190b27da033;p=sbcl.git diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index 4182448..11b3add 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -2468,12 +2468,26 @@ maybe_gc(os_context_t *context) */ #ifndef LISP_FEATURE_WIN32 if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL) { - thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0); - check_gc_signals_unblocked_or_lose(); + sigset_t *context_sigmask = os_context_sigmask_addr(context); +#ifdef LISP_FEATURE_SB_THREAD + /* What if the context we'd like to restore has GC signals + * blocked? Just skip the GC: we can't set GC_PENDING, because + * that would block the next attempt, and we don't know when + * we'd next check for it -- and it's hard to be sure that + * unblocking would be safe. */ + if (sigismember(context_sigmask,SIG_STOP_FOR_GC)) { + undo_fake_foreign_function_call(context); + return 1; + } +#endif + thread_sigmask(SIG_SETMASK, context_sigmask, 0); } else unblock_gc_signals(); #endif + /* SIG_STOP_FOR_GC needs to be enabled before we can call lisp: + * otherwise two threads racing here may deadlock: the other will + * wait on the GC lock, and the other cannot stop the first one... */ funcall0(SymbolFunction(SUB_GC)); undo_fake_foreign_function_call(context); return 1;