>From 9b8698bffa31802684e29cea6ce05123e0f79283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Wed, 21 Sep 2011 15:22:52 +0100 Subject: [PATCH] timeout: handle implicitly created threads On some systems like glibc on kFreeBSD, a thread is implicitly created when timer_settime() is used. This breaks our scheme to ignore signals we've sent ourselves. * src/timeout.c (send_sig): Change the scheme used to ignore signals we've sent ourselves, to a more robust but perhaps limited scheme of ignoring all signals of a certain type after we've sent that signal to the job. --- src/timeout.c | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/timeout.c b/src/timeout.c index d734e4e..59b937e 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -77,7 +77,6 @@ static int timed_out; static int term_signal = SIGTERM; /* same default as kill command. */ static int monitored_pid; -static int sigs_to_ignore[NSIG]; /* so monitor can ignore sigs it resends. */ static double kill_after; static bool foreground; /* whether to use another program group. */ @@ -141,12 +140,20 @@ settimeout (double duration) alarm (timeint); } -/* send sig to group but not ourselves. - * FIXME: Is there a better way to achieve this? */ +/* send SIG avoiding the current process. */ + static int send_sig (int where, int sig) { - sigs_to_ignore[sig] = 1; + /* If sending to the group, then ignore the signal, + so we don't go into a signal loop. Note that this will ignore any of the + signals registered in install_signal_handlers(), that are sent after we + propagate the first one, which hopefully won't be an issue. Note this + process can be implicitly multithreaded due to some timer_settime() + implementations, therefore a signal sent to the group, can be sent + multiple times to this process. */ + if (where == 0) + signal (sig, SIG_IGN); return kill (where, sig); } @@ -160,11 +167,6 @@ cleanup (int sig) } if (monitored_pid) { - if (sigs_to_ignore[sig]) - { - sigs_to_ignore[sig] = 0; - return; - } if (kill_after) { /* Start a new timeout after which we'll send SIGKILL. */ -- 1.7.6