summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--runtime/wti.c11
-rwxr-xr-xtests/diag.sh2
3 files changed, 13 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index b00b0b61..1066b734 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,8 @@
---------------------------------------------------------------------------
Version 5.1.6 [v5-beta] (rgerhards), 2009-09-??
- feature imports from v4.5.6
+- bugfix: potential race condition when queue worker threads were
+ terminated
- bugfixes imported from 4.5.4:
* bugfix: potential segfault in stream writer on destruction
* bugfix: potential race in object loader (obj.c) during use/release
diff --git a/runtime/wti.c b/runtime/wti.c
index 9d0560dd..e624899b 100644
--- a/runtime/wti.c
+++ b/runtime/wti.c
@@ -114,7 +114,12 @@ wtiSetState(wti_t *pThis, bool bNewVal)
/* Cancel the thread. If the thread is not running. But it is save and legal to
- * call wtiCancelThrd() in such situations.
+ * call wtiCancelThrd() in such situations. This function only returns when the
+ * thread has terminated. Else we may get race conditions all over the code...
+ * Note that when waiting for the thread to terminate, we do a busy wait, checking
+ * progress every 10ms. It is very unlikely that we will ever cancel a thread
+ * and, if so, it will only happen at the end of the rsyslog run. So doing this
+ * kind of not optimal wait is considered preferable over using condition variables.
* rgerhards, 2008-02-26
*/
rsRetVal
@@ -127,6 +132,10 @@ wtiCancelThrd(wti_t *pThis)
if(wtiGetState(pThis)) {
dbgoprint((obj_t*) pThis, "canceling worker thread\n");
pthread_cancel(pThis->thrdID);
+ /* now wait until the thread terminates... */
+ while(wtiGetState(pThis)) {
+ srSleep(0, 10000);
+ }
}
RETiRet;
diff --git a/tests/diag.sh b/tests/diag.sh
index 13bb877d..b2bd13ac 100755
--- a/tests/diag.sh
+++ b/tests/diag.sh
@@ -9,7 +9,7 @@
#valgrind="valgrind --tool=drd --log-fd=1"
#valgrind="valgrind --tool=helgrind --log-fd=1"
#set -o xtrace
-#export RSYSLOG_DEBUG="debug nostdout printmutexaction"
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
#export RSYSLOG_DEBUGLOG="log"
case $1 in
'init') $srcdir/killrsyslog.sh # kill rsyslogd if it runs for some reason