summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-05-25 13:02:06 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2009-05-25 13:02:06 +0200
commit7a7ec37f99f3dd5120952e6ca6263dd72061abb1 (patch)
treef2054bf445ed844606172346210f244a67db2cc7 /runtime
parentaaef9aa018dc030a7b5b2585bad19812ff214fab (diff)
downloadrsyslog-7a7ec37f99f3dd5120952e6ca6263dd72061abb1.tar.gz
rsyslog-7a7ec37f99f3dd5120952e6ca6263dd72061abb1.tar.xz
rsyslog-7a7ec37f99f3dd5120952e6ca6263dd72061abb1.zip
improved testbench / solved imdiag race condition
imdiag/imtcp had a modload race condition (as imdiag is a testing aid, this has no implications for production deployments). Also, I replaced netcat by a custom program to talk to imdiag. This, for the first time ever, is now a Java program. I plan to add some GUI troubleshooting tools and thought it is a good idea to start doing things in Java that can simply be done in that language.
Diffstat (limited to 'runtime')
-rw-r--r--runtime/modules.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/runtime/modules.c b/runtime/modules.c
index 9fdb48e7..3e8662a3 100644
--- a/runtime/modules.c
+++ b/runtime/modules.c
@@ -40,6 +40,7 @@
#include <time.h>
#include <assert.h>
#include <errno.h>
+#include <pthread.h>
#ifdef OS_BSD
# include "libgen.h"
#endif
@@ -61,6 +62,14 @@
DEFobjStaticHelpers
DEFobjCurrIf(errmsg)
+/* we must ensure that only one thread at one time tries to load or unload
+ * modules, otherwise we may see race conditions. This first came up with
+ * imdiag/imtcp, which both use the same stream drivers. Below is the mutex
+ * for that handling.
+ * rgerhards, 2009-05-25
+ */
+static pthread_mutex_t mutLoadUnload;
+
static modInfo_t *pLoadedModules = NULL; /* list of currently-loaded modules */
static modInfo_t *pLoadedModulesLast = NULL; /* tail-pointer */
@@ -479,6 +488,8 @@ modUnlinkAndDestroy(modInfo_t **ppThis)
pThis = *ppThis;
assert(pThis != NULL);
+ pthread_mutex_lock(&mutLoadUnload);
+
/* first check if we are permitted to unload */
if(pThis->eType == eMOD_LIB) {
if(pThis->uRefCnt > 0) {
@@ -513,6 +524,7 @@ modUnlinkAndDestroy(modInfo_t **ppThis)
moduleDestruct(pThis);
finalize_it:
+ pthread_mutex_unlock(&mutLoadUnload);
RETiRet;
}
@@ -587,6 +599,8 @@ Load(uchar *pModName)
assert(pModName != NULL);
dbgprintf("Requested to load module '%s'\n", pModName);
+ pthread_mutex_lock(&mutLoadUnload);
+
iModNameLen = strlen((char *) pModName);
if(iModNameLen > 3 && !strcmp((char *) pModName + iModNameLen - 3, ".so")) {
iModNameLen -= 3;
@@ -696,6 +710,7 @@ Load(uchar *pModName)
}
finalize_it:
+ pthread_mutex_unlock(&mutLoadUnload);
RETiRet;
}
@@ -791,6 +806,7 @@ BEGINObjClassExit(module, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MA
CODESTARTObjClassExit(module)
/* release objects we no longer need */
objRelease(errmsg, CORE_COMPONENT);
+ pthread_mutex_destroy(&mutLoadUnload);
# ifdef DEBUG
modUsrPrintAll(); /* debug aid - TODO: integrate with debug.c, at least the settings! */
@@ -833,6 +849,7 @@ ENDobjQueryInterface(module)
*/
BEGINAbstractObjClassInit(module, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */
uchar *pModPath;
+ pthread_mutexattr_t mutAttr;
/* use any module load path specified in the environment */
if((pModPath = (uchar*) getenv("RSYSLOG_MODDIR")) != NULL) {
@@ -850,6 +867,10 @@ BEGINAbstractObjClassInit(module, 1, OBJ_IS_CORE_MODULE) /* class, version - CHA
SetModDir(glblModPath);
}
+ pthread_mutexattr_init(&mutAttr);
+ pthread_mutexattr_settype(&mutAttr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&mutLoadUnload, &mutAttr);
+
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
ENDObjClassInit(module)