From 495ae8752084b896f29d92e33028f44269e1d1b1 Mon Sep 17 00:00:00 2001 From: Andre Lorbach Date: Mon, 15 Jul 2013 08:17:08 +0200 Subject: bugfix: 100% CPU utilization when DA queue became full --- ChangeLog | 1 + runtime/queue.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index fbe61c0e..058191e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ Version 7.4.3 [v7.4-stable] 2013-07-?? - bugfix: potential segfault during startup on invalid config could happen if invalid actions were present, which could lead to improper handling in optimizer. +- bugfix: 100% CPU utilization when DA queue became full - bugfix: omlibdbi did not properly close connection on some errors This happened to errors occuring in Begin/End Transaction entry points. diff --git a/runtime/queue.c b/runtime/queue.c index 3ae74287..d5ad37a1 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -1913,8 +1913,16 @@ ConsumerDA(qqueue_t *pThis, wti_t *pWti) /* iterate over returned results and enqueue them in DA queue */ for(i = 0 ; i < pWti->batch.nElem && !pThis->bShutdownImmediate ; i++) { - CHKiRet(qqueueEnqMsg(pThis->pqDA, eFLOWCTL_NO_DELAY, - MsgAddRef(pWti->batch.pElem[i].pMsg))); + iRet = qqueueEnqMsg(pThis->pqDA, eFLOWCTL_NO_DELAY, MsgAddRef(pWti->batch.pElem[i].pMsg)); + if(iRet != RS_RET_OK) { + if(iRet == RS_RET_ERR_QUEUE_EMERGENCY) { + /* Queue emergency error occured */ + DBGOPRINT((obj_t*) pThis, "ConsumerDA:qqueueEnqMsg caught RS_RET_ERR_QUEUE_EMERGENCY, aborting loop.\n"); + FINALIZE; + } else { + DBGOPRINT((obj_t*) pThis, "ConsumerDA:qqueueEnqMsg item (%d) returned with error state: '%d'\n", i, iRet); + } + } pWti->batch.eltState[i] = BATCH_STATE_COMM; /* commited to other queue! */ } @@ -1922,10 +1930,14 @@ ConsumerDA(qqueue_t *pThis, wti_t *pWti) pthread_setcancelstate(iCancelStateSave, NULL); finalize_it: + if(iRet != RS_RET_OK && iRet != RS_RET_ERR_QUEUE_EMERGENCY) { + iRet = RS_RET_OK; + } + /* now we are done, but potentially need to re-aquire the mutex */ if(bNeedReLock) d_pthread_mutex_lock(pThis->mut); - DBGOPRINT((obj_t*) pThis, "DAConsumer returns with iRet %d\n", iRet); + RETiRet; } -- cgit v1.2.3 From b6d350ab9c212923dcfcf3b160af83b3c078f1bc Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Jul 2013 15:22:59 +0200 Subject: fix regression that caused freeInstance not to be correctly called was introduced July, 5th 2013 by commit 8ee2b0b1610fbf4dff20453d188f379583410b42 --- grammar/rainerscript.c | 2 +- grammar/rainerscript.h | 2 +- runtime/ruleset.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c index e3e7cb32..0f0b469c 100644 --- a/grammar/rainerscript.c +++ b/grammar/rainerscript.c @@ -2450,7 +2450,7 @@ cnfstmtNew(unsigned s_type) void cnfstmtDestructLst(struct cnfstmt *root); /* delete a single stmt */ -void +static void cnfstmtDestruct(struct cnfstmt *stmt) { switch(stmt->nodetype) { diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h index 31b2eb93..d00cc4c3 100644 --- a/grammar/rainerscript.h +++ b/grammar/rainerscript.h @@ -331,7 +331,7 @@ struct cnfstmt * cnfstmtNewSet(char *var, struct cnfexpr *expr); struct cnfstmt * cnfstmtNewUnset(char *var); struct cnfstmt * cnfstmtNewCall(es_str_t *name); struct cnfstmt * cnfstmtNewContinue(void); -void cnfstmtDestruct(struct cnfstmt *root); +void cnfstmtDestructLst(struct cnfstmt *root); void cnfstmtOptimize(struct cnfstmt *root); struct cnfarray* cnfarrayNew(es_str_t *val); struct cnfarray* cnfarrayDup(struct cnfarray *old); diff --git a/runtime/ruleset.c b/runtime/ruleset.c index e3348938..5bf7ac03 100644 --- a/runtime/ruleset.c +++ b/runtime/ruleset.c @@ -742,7 +742,7 @@ CODESTARTobjDestruct(ruleset) parser.DestructParserList(&pThis->pParserLst); } free(pThis->pszName); - cnfstmtDestruct(pThis->root); + cnfstmtDestructLst(pThis->root); ENDobjDestruct(ruleset) @@ -952,7 +952,7 @@ rulesetProcessCnf(struct cnfobj *o) errmsg.LogError(0, RS_RET_RULESET_EXISTS, "error: ruleset '%s' specified more than once", rsName); - cnfstmtDestruct(o->script); + cnfstmtDestructLst(o->script); ABORT_FINALIZE(RS_RET_RULESET_EXISTS); } else if(localRet != RS_RET_NOT_FOUND) { ABORT_FINALIZE(localRet); -- cgit v1.2.3