aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vcl/vcl_locked.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/vcl/vcl_locked.c b/src/vcl/vcl_locked.c
index e32e96ceaa5..f38df8fbf47 100644
--- a/src/vcl/vcl_locked.c
+++ b/src/vcl/vcl_locked.c
@@ -140,6 +140,7 @@ typedef struct vls_local_
pthread_mutex_t vls_mt_mq_mlock; /**< vcl mq lock */
pthread_mutex_t vls_mt_spool_mlock; /**< vcl select or pool lock */
volatile u8 select_mp_check; /**< flag set if select checks done */
+ struct sigaction old_sa; /**< old sigaction to restore */
} vls_process_local_t;
static vls_process_local_t vls_local;
@@ -1798,8 +1799,6 @@ vls_handle_pending_wrk_cleanup (void)
vec_reset_length (vls_wrk->pending_vcl_wrk_cleanup);
}
-static struct sigaction old_sa;
-
static void
vls_intercept_sigchld_handler (int signum, siginfo_t * si, void *uc)
{
@@ -1809,7 +1808,7 @@ vls_intercept_sigchld_handler (int signum, siginfo_t * si, void *uc)
if (vcl_get_worker_index () == ~0)
return;
- if (sigaction (SIGCHLD, &old_sa, 0))
+ if (sigaction (SIGCHLD, &vlsl->old_sa, 0))
{
VERR ("couldn't restore sigchld");
exit (-1);
@@ -1823,6 +1822,9 @@ vls_intercept_sigchld_handler (int signum, siginfo_t * si, void *uc)
if (!child_wrk)
goto done;
+ /* TODO we need to support multiple children */
+ wrk->forked_child = ~0;
+
if (si && si->si_pid != child_wrk->current_pid)
{
VDBG (0, "unexpected child pid %u", si->si_pid);
@@ -1838,14 +1840,15 @@ vls_intercept_sigchld_handler (int signum, siginfo_t * si, void *uc)
vec_add1 (vls_wrk->pending_vcl_wrk_cleanup, child_wrk->wrk_index);
done:
- if (old_sa.sa_flags & SA_SIGINFO)
+ if (vlsl->old_sa.sa_flags & SA_SIGINFO)
{
- void (*fn) (int, siginfo_t *, void *) = old_sa.sa_sigaction;
- fn (signum, si, uc);
+ void (*fn) (int, siginfo_t *, void *) = vlsl->old_sa.sa_sigaction;
+ if (fn)
+ fn (signum, si, uc);
}
else
{
- void (*fn) (int) = old_sa.sa_handler;
+ void (*fn) (int) = vlsl->old_sa.sa_handler;
if (fn)
fn (signum);
}
@@ -1855,7 +1858,7 @@ static void
vls_incercept_sigchld ()
{
struct sigaction sa;
- if (old_sa.sa_sigaction)
+ if (vlsl->old_sa.sa_sigaction)
{
VDBG (0, "have intercepted sigchld");
return;
@@ -1863,11 +1866,17 @@ vls_incercept_sigchld ()
clib_memset (&sa, 0, sizeof (sa));
sa.sa_sigaction = vls_intercept_sigchld_handler;
sa.sa_flags = SA_SIGINFO;
- if (sigaction (SIGCHLD, &sa, &old_sa))
+ if (sigaction (SIGCHLD, &sa, &vlsl->old_sa))
{
VERR ("couldn't intercept sigchld");
exit (-1);
}
+
+ /* Not entirely clear how, but some processes can clear old_sa after fork
+ * and subsequently fork and register vls_intercept_sigchld_handler as
+ * old_sa handler leading to recursion */
+ if (vlsl->old_sa.sa_sigaction == vls_intercept_sigchld_handler)
+ vlsl->old_sa.sa_sigaction = 0;
}
static void