File 0011-The-shutdown-sequence-in-wtp-relies-for-its-operatio.patch of Package rsyslog.6132
From fae3e420f4e1da2b60400f4f06fdf41624e5fdf9 Mon Sep 17 00:00:00 2001
From: Tomas Sykora <tosykora@redhat.com>
Date: Thu, 24 Nov 2016 04:24:35 -0500
Subject: [PATCH] The shutdown sequence in wtp relies for its operation on
signals and cancelation cleanup handlers. Previously, trying to shutdown a
thread that has not yet been properly initialized could lead to a deadlock.
This change makes wtpStartWrkr() synchronous in regard to the initialization
of the newly created thread.
Thanks to Rado Sroka for the analysis and an initial patch.
---
runtime/wtp.c | 13 +++++++++++++
runtime/wtp.h | 1 +
2 files changed, 14 insertions(+)
diff --git a/runtime/wtp.c b/runtime/wtp.c
index 7545080e..9b36c2e4 100644
--- a/runtime/wtp.c
+++ b/runtime/wtp.c
@@ -88,6 +88,7 @@ static rsRetVal NotImplementedDummy(void) { return RS_RET_NOT_IMPLEMENTED; }
*/
BEGINobjConstruct(wtp) /* be sure to specify the object type also in END macro! */
pthread_mutex_init(&pThis->mutWtp, NULL);
+ pthread_cond_init(&pThis->condThrdInitDone, NULL);
pthread_cond_init(&pThis->condThrdTrm, NULL);
pthread_attr_init(&pThis->attrThrd);
/* Set thread scheduling policy to default */
@@ -156,6 +157,7 @@ CODESTARTobjDestruct(wtp)
/* actual destruction */
pthread_cond_destroy(&pThis->condThrdTrm);
+ pthread_cond_destroy(&pThis->condThrdInitDone);
pthread_mutex_destroy(&pThis->mutWtp);
pthread_attr_destroy(&pThis->attrThrd);
DESTROY_ATOMIC_HELPER_MUT(pThis->mutCurNumWrkThrd);
@@ -386,6 +388,12 @@ wtpWorker(void *arg) /* the arg is actually a wti object, even though we are in
# endif
pthread_cleanup_push(wtpWrkrExecCancelCleanup, pWti);
+
+ /* let the parent know we're done with initialization */
+ d_pthread_mutex_lock(&pThis->mutWtp);
+ pthread_cond_broadcast(&pThis->condThrdInitDone);
+ d_pthread_mutex_unlock(&pThis->mutWtp);
+
wtiWorker(pWti);
pthread_cleanup_pop(0);
wtpWrkrExecCleanup(pWti);
@@ -437,6 +445,11 @@ wtpStartWrkr(wtp_t *pThis)
wtpGetDbgHdr(pThis), iState,
ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd));
+ /* wait for the new thread to initialize its signal mask and
+ * cancelation cleanup handler before proceeding
+ */
+ d_pthread_cond_wait(&pThis->condThrdInitDone, &pThis->mutWtp);
+
finalize_it:
d_pthread_mutex_unlock(&pThis->mutWtp);
RETiRet;
diff --git a/runtime/wtp.h b/runtime/wtp.h
index 95977f87..2ed6ae14 100644
--- a/runtime/wtp.h
+++ b/runtime/wtp.h
@@ -50,6 +50,7 @@ struct wtp_s {
rsRetVal (*pConsumer)(void *); /* user-supplied consumer function for dewtpd messages */
/* synchronization variables */
pthread_mutex_t mutWtp; /* mutex for the wtp's thread management */
+ pthread_cond_t condThrdInitDone; /* signalled when a new thread is ready for work */
pthread_cond_t condThrdTrm;/* signalled when threads terminate */
/* end sync variables */
/* user objects */
--
2.15.0