summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-09-18 12:19:33 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2008-09-18 12:19:33 +0200
commit4c96ebdcfe075e80810b01257cf21ea1c9b3ec0e (patch)
treeb6768398d8d55c04e045b5213e11b952484025e8
parent988989e49ef8639123c83383ba256c4e67679c8d (diff)
downloadrsyslog-4c96ebdcfe075e80810b01257cf21ea1c9b3ec0e.tar.gz
rsyslog-4c96ebdcfe075e80810b01257cf21ea1c9b3ec0e.tar.xz
rsyslog-4c96ebdcfe075e80810b01257cf21ea1c9b3ec0e.zip
bugfix: potential race condition when adding messages to queue
There was a wrong order of mutex lock operations. It is hard to believe that really caused problems, but in theory it could and with threading we often see that theory becomes practice if something is only used long enough on a fast enough machine with enough CPUs ;)
-rw-r--r--ChangeLog5
-rw-r--r--runtime/atomic.h8
-rw-r--r--runtime/debug.h3
-rw-r--r--runtime/queue.c12
-rw-r--r--tools/syslogd.c7
5 files changed, 22 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 125b0ada..23ac95fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,11 @@ Version 3.21.5 [DEVEL] (rgerhards), 2008-09-??
local host as it knows itself.
- re-enabled gcc builtin atomic operations and added a proper
./configure check
+- bugfix: potential race condition when adding messages to queue
+ There was a wrong order of mutex lock operations. It is hard to
+ believe that really caused problems, but in theory it could and with
+ threading we often see that theory becomes practice if something is only
+ used long enough on a fast enough machine with enough CPUs ;)
---------------------------------------------------------------------------
Version 3.21.4 [DEVEL] (rgerhards), 2008-09-04
- removed compile time fixed message size limit (was 2K), limit can now
diff --git a/runtime/atomic.h b/runtime/atomic.h
index d6811628..d15f78ee 100644
--- a/runtime/atomic.h
+++ b/runtime/atomic.h
@@ -41,11 +41,15 @@
* They simply came in too late. -- rgerhards, 2008-04-02
*/
#ifdef HAVE_ATOMIC_BUILTINS
-# define ATOMIC_INC(data) ((void) __sync_fetch_and_add(&data, 1))
-# define ATOMIC_DEC_AND_FETCH(data) __sync_sub_and_fetch(&data, 1)
+# define ATOMIC_INC(data) ((void) __sync_fetch_and_add(&(data), 1))
+# define ATOMIC_DEC_AND_FETCH(data) __sync_sub_and_fetch(&(data), 1)
+# define ATOMIC_FETCH_32BIT(data) ((unsigned) __sync_fetch_and_and(&(data), 0xffffffff))
+# define ATOMIC_STORE_1_TO_32BIT(data) __sync_lock_test_and_set(&(data), 1)
#else
# warning "atomic builtins not available, using nul operations"
# define ATOMIC_INC(data) (++(data))
+# define ATOMIC_FETCH_32BIT(data) (data)
+# define ATOMIC_STORE_1_TO_32BIT(data) (data) = 1
#endif
#endif /* #ifndef INCLUDED_ATOMIC_H */
diff --git a/runtime/debug.h b/runtime/debug.h
index 214b7c05..d9d576b5 100644
--- a/runtime/debug.h
+++ b/runtime/debug.h
@@ -130,7 +130,8 @@ void dbgPrintAllDebugInfo(void);
/* debug aides */
-#ifdef RTINST
+//#ifdef RTINST
+#if 0 // temporarily removed for helgrind
#define d_pthread_mutex_lock(x) dbgMutexLock(x, pdbgFuncDB, __LINE__, dbgCALLStaCK_POP_POINT )
#define d_pthread_mutex_unlock(x) dbgMutexUnlock(x, pdbgFuncDB, __LINE__, dbgCALLStaCK_POP_POINT )
#define d_pthread_cond_wait(cond, mut) dbgCondWait(cond, mut, pdbgFuncDB, __LINE__, dbgCALLStaCK_POP_POINT )
diff --git a/runtime/queue.c b/runtime/queue.c
index 7e7d4152..c0a37019 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -2171,17 +2171,17 @@ queueEnqObj(queue_t *pThis, flowControl_t flowCtlType, void *pUsr)
finalize_it:
if(pThis->qType != QUEUETYPE_DIRECT) {
- d_pthread_mutex_unlock(pThis->mut);
+ /* make sure at least one worker is running. */
+ if(pThis->qType != QUEUETYPE_DIRECT) {
+ queueAdviseMaxWorkers(pThis);
+ }
+ /* and release the mutex */
i = pthread_cond_signal(&pThis->notEmpty);
+ d_pthread_mutex_unlock(pThis->mut);
dbgoprint((obj_t*) pThis, "EnqueueMsg signaled condition (%d)\n", i);
pthread_setcancelstate(iCancelStateSave, NULL);
}
- /* make sure at least one worker is running. */
- if(pThis->qType != QUEUETYPE_DIRECT) {
- queueAdviseMaxWorkers(pThis);
- }
-
RETiRet;
}
diff --git a/tools/syslogd.c b/tools/syslogd.c
index b6e1d826..3a637dd8 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -2832,9 +2832,8 @@ static rsRetVal mainThread()
CHKiRet(init());
- if(Debug) {
+ if(Debug && debugging_on) {
dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n");
- debugging_on = 1;
}
/* Send a signal to the parent so it can terminate.
*/
@@ -3082,9 +3081,9 @@ doGlblProcessInit(void)
fputs(" Already running.\n", stderr);
exit(1); /* "good" exit, done if syslogd is already running */
}
- }
- else
+ } else {
debugging_on = 1;
+ }
/* tuck my process id away */
dbgprintf("Writing pidfile %s.\n", PidFile);