mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-11 22:31:12 +02:00
Lock ordering: don't allocate when in critical section (scm_sigaction_for_thread)
This fixes the following helgrind report. Thread #1: lock order "0x4114748 before 0x4331084" violated at 0x40234F7: pthread_mutex_lock (hg_intercepts.c:408) by 0x407A55F: deval (eval.c:4077) by 0x407A071: scm_dapply (eval.c:5012) by 0x407888A: scm_apply (eval.c:4811) by 0x407E20C: scm_call_0 (eval.c:4666) by 0x406BDF7: scm_dynamic_wind (dynwind.c:111) by 0x407620C: ceval (eval.c:4571) by 0x407E8D9: scm_primitive_eval_x (eval.c:5921) by 0x407E934: scm_eval_x (eval.c:5956) by 0x40B9140: scm_shell (script.c:737) by 0x4095AC5: invoke_main_func (init.c:367) by 0x4065A81: c_body (continuations.c:349) Required order was established by acquisition of lock at 0x4114748 at 0x40234F7: pthread_mutex_lock (hg_intercepts.c:408) by 0x40B7BE1: scm_sigaction_for_thread (scmsigs.c:339) by 0x40911DE: scm_gsubr_apply (gsubr.c:223) by 0x4079E36: scm_dapply (eval.c:4930) by 0x407AB68: deval (eval.c:4378) by 0x407A071: scm_dapply (eval.c:5012) by 0x407888A: scm_apply (eval.c:4811) by 0x407E1D0: scm_call_1 (eval.c:4672) by 0x407FEEE: scm_map (eval.c:5489) by 0x407BDCC: deval (eval.c:4367) by 0x407D197: deval (eval.c:3698) by 0x407A071: scm_dapply (eval.c:5012) followed by a later acquisition of lock at 0x4331084 at 0x40234F7: pthread_mutex_lock (hg_intercepts.c:408) by 0x40DC397: scm_enter_guile (threads.c:377) by 0x40DC8F4: scm_pthread_mutex_lock (threads.c:1485) by 0x4083FAA: scm_gc_for_newcell (gc.c:484) by 0x40A9781: scm_cons (inline.h:115) by 0x4079867: scm_dapply (eval.c:4850) by 0x407888A: scm_apply (eval.c:4811) by 0x40796D6: scm_call_3 (eval.c:4684) by 0x409A7C2: module_variable (modules.c:302) by 0x409A7EE: module_variable (modules.c:312) by 0x409A962: scm_sym2var (modules.c:466) by 0x40738F4: scm_lookupcar1 (eval.c:2874) * libguile/scmsigs.c (close_1): Renamed `handler_to_async'; also handle #f case and wrapping the async in a cons, if necessary. (install_handler): Pass in async instead of constructing it; combine two branches into one. (scm_sigaction_for_thread): Allocate async upfront instead of inside the critical section, and pass it to install_handler calls. Leave critical section before signaling out-of-range error.
This commit is contained in:
parent
58bef38c0a
commit
2bfcaf2605
1 changed files with 25 additions and 23 deletions
|
@ -108,10 +108,20 @@ static SIGRETTYPE (*orig_handlers[NSIG])(int);
|
|||
#endif
|
||||
|
||||
static SCM
|
||||
close_1 (SCM proc, SCM arg)
|
||||
handler_to_async (SCM handler, int signum)
|
||||
{
|
||||
return scm_primitive_eval_x (scm_list_3 (scm_sym_lambda, SCM_EOL,
|
||||
scm_list_2 (proc, arg)));
|
||||
if (scm_is_false (handler))
|
||||
return SCM_BOOL_F;
|
||||
else
|
||||
{
|
||||
SCM async = scm_primitive_eval_x (scm_list_3 (scm_sym_lambda, SCM_EOL,
|
||||
scm_list_2 (handler,
|
||||
scm_from_int (signum))));
|
||||
#if !SCM_USE_PTHREAD_THREADS
|
||||
async = scm_cons (async, SCM_BOOL_F);
|
||||
#endif
|
||||
return async;
|
||||
}
|
||||
}
|
||||
|
||||
#if SCM_USE_PTHREAD_THREADS
|
||||
|
@ -239,23 +249,10 @@ ensure_signal_delivery_thread ()
|
|||
#endif /* !SCM_USE_PTHREAD_THREADS */
|
||||
|
||||
static void
|
||||
install_handler (int signum, SCM thread, SCM handler)
|
||||
install_handler (int signum, SCM thread, SCM handler, SCM async)
|
||||
{
|
||||
if (scm_is_false (handler))
|
||||
{
|
||||
SCM_SIMPLE_VECTOR_SET (*signal_handlers, signum, SCM_BOOL_F);
|
||||
SCM_SIMPLE_VECTOR_SET (signal_handler_asyncs, signum, SCM_BOOL_F);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCM async = close_1 (handler, scm_from_int (signum));
|
||||
#if !SCM_USE_PTHREAD_THREADS
|
||||
async = scm_cons (async, SCM_BOOL_F);
|
||||
#endif
|
||||
SCM_SIMPLE_VECTOR_SET (*signal_handlers, signum, handler);
|
||||
SCM_SIMPLE_VECTOR_SET (signal_handler_asyncs, signum, async);
|
||||
}
|
||||
|
||||
SCM_SIMPLE_VECTOR_SET (*signal_handlers, signum, handler);
|
||||
SCM_SIMPLE_VECTOR_SET (signal_handler_asyncs, signum, async);
|
||||
SCM_SIMPLE_VECTOR_SET (signal_handler_threads, signum, thread);
|
||||
}
|
||||
|
||||
|
@ -308,6 +305,7 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0,
|
|||
int save_handler = 0;
|
||||
|
||||
SCM old_handler;
|
||||
SCM async;
|
||||
|
||||
csig = scm_to_signed_integer (signum, 0, NSIG-1);
|
||||
|
||||
|
@ -334,6 +332,10 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0,
|
|||
SCM_MISC_ERROR ("thread has already exited", SCM_EOL);
|
||||
}
|
||||
|
||||
/* Allocate upfront, as we can't do it inside the critical
|
||||
section. */
|
||||
async = handler_to_async (handler, csig);
|
||||
|
||||
ensure_signal_delivery_thread ();
|
||||
|
||||
SCM_CRITICAL_SECTION_START;
|
||||
|
@ -351,7 +353,7 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0,
|
|||
#else
|
||||
chandler = (SIGRETTYPE (*) (int)) handler_int;
|
||||
#endif
|
||||
install_handler (csig, SCM_BOOL_F, SCM_BOOL_F);
|
||||
install_handler (csig, SCM_BOOL_F, SCM_BOOL_F, async);
|
||||
}
|
||||
else
|
||||
SCM_OUT_OF_RANGE (2, handler);
|
||||
|
@ -366,7 +368,7 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0,
|
|||
{
|
||||
action = orig_handlers[csig];
|
||||
orig_handlers[csig].sa_handler = SIG_ERR;
|
||||
install_handler (csig, SCM_BOOL_F, SCM_BOOL_F);
|
||||
install_handler (csig, SCM_BOOL_F, SCM_BOOL_F, async);
|
||||
}
|
||||
#else
|
||||
if (orig_handlers[csig] == SIG_ERR)
|
||||
|
@ -375,7 +377,7 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0,
|
|||
{
|
||||
chandler = orig_handlers[csig];
|
||||
orig_handlers[csig] = SIG_ERR;
|
||||
install_handler (csig, SCM_BOOL_F, SCM_BOOL_F);
|
||||
install_handler (csig, SCM_BOOL_F, SCM_BOOL_F, async);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -391,7 +393,7 @@ SCM_DEFINE (scm_sigaction_for_thread, "sigaction", 1, 3, 0,
|
|||
if (orig_handlers[csig] == SIG_ERR)
|
||||
save_handler = 1;
|
||||
#endif
|
||||
install_handler (csig, thread, handler);
|
||||
install_handler (csig, thread, handler, async);
|
||||
}
|
||||
|
||||
/* XXX - Silently ignore setting handlers for `program error signals'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue