summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-07-01 14:33:19 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2009-07-01 14:33:19 +0200
commit7bfa03bdc0b73647ffdbe4b73e5c1649af665fbf (patch)
tree545a24dd681bd28455702b06dff41f7814bf3561 /runtime
parentd6faee67b413d1f257c96a14e46f15ec1868a365 (diff)
downloadrsyslog-7bfa03bdc0b73647ffdbe4b73e5c1649af665fbf.tar.gz
rsyslog-7bfa03bdc0b73647ffdbe4b73e5c1649af665fbf.tar.xz
rsyslog-7bfa03bdc0b73647ffdbe4b73e5c1649af665fbf.zip
now put the new property-based methods to good use
... hopefully reducing the number of allocs/frees as well as overall memory usage in a busy system (plus that these shared properties hopefully remain in cache longer than its single-instance counterparts...)
Diffstat (limited to 'runtime')
-rw-r--r--runtime/msg.c58
-rw-r--r--runtime/msg.h4
-rw-r--r--runtime/prop.c76
-rw-r--r--runtime/prop.h2
4 files changed, 100 insertions, 40 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index d3645664..6c272d1f 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -1838,21 +1838,22 @@ void MsgSetRcvFrom(msg_t *pThis, prop_t *new)
pThis->pRcvFrom = new;
}
-/* to be removed soon: work-around for those tht can not natively generate a
- * property.
- * rgerhards, 2009-06-29
+
+/* This is used to set the property via a string. This function should not be
+ * called if there is a reliable way for a caller to make sure that the
+ * same name can be used across multiple messages. However, if it can not
+ * ensure that, calling this function is the second best thing, because it
+ * will re-use the previously created property if it contained the same
+ * name (but it works only for the immediate previous).
+ * rgerhards, 2009-06-31
*/
-void MsgSetRcvFromStr(msg_t *pThis, uchar *psz, int len)
+void MsgSetRcvFromStr(msg_t *pThis, uchar *psz, int len, prop_t **ppProp)
{
- prop_t *pProp;
assert(pThis != NULL);
+ assert(ppProp != NULL);
- /* we need to create a property */
- prop.Construct(&pProp);
- prop.SetString(pProp, psz, len);
- prop.ConstructFinalize(pProp);
- MsgSetRcvFrom(pThis, pProp);
- prop.Destruct(&pProp);
+ prop.CreateOrReuseStringProp(ppProp, psz, len);
+ MsgSetRcvFrom(pThis, *ppProp);
}
@@ -1875,24 +1876,27 @@ rsRetVal MsgSetRcvFromIP(msg_t *pThis, prop_t *new)
}
-/* to be removed soon: work-around for those tht can not natively generate a
- * property.
- * rgerhards, 2009-06-29
+/* This is used to set the property via a string. This function should not be
+ * called if there is a reliable way for a caller to make sure that the
+ * same name can be used across multiple messages. However, if it can not
+ * ensure that, calling this function is the second best thing, because it
+ * will re-use the previously created property if it contained the same
+ * name (but it works only for the immediate previous).
+ * rgerhards, 2009-06-31
*/
-rsRetVal MsgSetRcvFromIPStr(msg_t *pThis, uchar *psz, int len)
+rsRetVal MsgSetRcvFromIPStr(msg_t *pThis, uchar *psz, int len, prop_t **ppProp)
{
- prop_t *pProp;
+ DEFiRet;
assert(pThis != NULL);
- /* we need to create a property */
- prop.Construct(&pProp);
- prop.SetString(pProp, psz, len);
- prop.ConstructFinalize(pProp);
- MsgSetRcvFromIP(pThis, pProp);
- prop.Destruct(&pProp);
- return RS_RET_OK;
+ CHKiRet(prop.CreateOrReuseStringProp(ppProp, psz, len));
+ MsgSetRcvFrom(pThis, *ppProp);
+
+finalize_it:
+ RETiRet;
}
+
/* rgerhards 2004-11-09: set HOSTNAME in msg object
* rgerhards, 2007-06-21:
* Does not return anything. If an error occurs, the hostname is
@@ -2901,6 +2905,8 @@ finalize_it:
rsRetVal MsgSetProperty(msg_t *pThis, var_t *pProp)
{
prop_t *myProp;
+ prop_t *propRcvFrom = NULL;
+ prop_t *propRcvFromIP = NULL;
DEFiRet;
ISOBJ_TYPE_assert(pThis, msg);
@@ -2935,9 +2941,11 @@ rsRetVal MsgSetProperty(msg_t *pThis, var_t *pProp)
MsgSetInputName(pThis, myProp);
prop.Destruct(&myProp);
} else if(isProp("pszRcvFromIP")) {
- MsgSetRcvFromIPStr(pThis, rsCStrGetSzStrNoNULL(pProp->val.pStr), rsCStrLen(pProp->val.pStr));
+ MsgSetRcvFromIPStr(pThis, rsCStrGetSzStrNoNULL(pProp->val.pStr), rsCStrLen(pProp->val.pStr), &propRcvFromIP);
+ prop.Destruct(&propRcvFromIP);
} else if(isProp("pszRcvFrom")) {
- MsgSetRcvFromStr(pThis, rsCStrGetSzStrNoNULL(pProp->val.pStr), rsCStrLen(pProp->val.pStr));
+ MsgSetRcvFromStr(pThis, rsCStrGetSzStrNoNULL(pProp->val.pStr), rsCStrLen(pProp->val.pStr), &propRcvFrom);
+ prop.Destruct(&propRcvFrom);
} else if(isProp("pszHOSTNAME")) {
MsgSetHOSTNAME(pThis, rsCStrGetSzStrNoNULL(pProp->val.pStr), rsCStrLen(pProp->val.pStr));
} else if(isProp("pCSStrucData")) {
diff --git a/runtime/msg.h b/runtime/msg.h
index 43f24435..c20fb005 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -150,9 +150,9 @@ void MsgSetRuleset(msg_t *pMsg, ruleset_t*);
rsRetVal MsgSetFlowControlType(msg_t *pMsg, flowControl_t eFlowCtl);
rsRetVal MsgSetStructuredData(msg_t *pMsg, char* pszStrucData);
void MsgSetRcvFrom(msg_t *pMsg, prop_t*);
-void MsgSetRcvFromStr(msg_t *pMsg, uchar* pszRcvFrom, int);
+void MsgSetRcvFromStr(msg_t *pMsg, uchar* pszRcvFrom, int, prop_t **);
rsRetVal MsgSetRcvFromIP(msg_t *pMsg, prop_t*);
-rsRetVal MsgSetRcvFromIPStr(msg_t *pMsg, uchar*, int);
+rsRetVal MsgSetRcvFromIPStr(msg_t *pThis, uchar *psz, int len, prop_t **ppProp);
void MsgSetHOSTNAME(msg_t *pMsg, uchar* pszHOSTNAME, int lenHOSTNAME);
rsRetVal MsgSetAfterPRIOffs(msg_t *pMsg, short offs);
void MsgSetMSGoffs(msg_t *pMsg, short offs);
diff --git a/runtime/prop.c b/runtime/prop.c
index 96ebe212..804f3491 100644
--- a/runtime/prop.c
+++ b/runtime/prop.c
@@ -41,6 +41,7 @@
#include "rsyslog.h"
#include "obj.h"
#include "obj-types.h"
+#include "unicode-helper.h"
#include "atomic.h"
#include "prop.h"
@@ -54,6 +55,21 @@ BEGINobjConstruct(prop) /* be sure to specify the object type also in END macro!
pThis->iRefCount = 1;
ENDobjConstruct(prop)
+
+/* destructor for the prop object */
+BEGINobjDestruct(prop) /* be sure to specify the object type also in END and CODESTART macros! */
+ int currRefCount;
+CODESTARTobjDestruct(prop)
+ currRefCount = ATOMIC_DEC_AND_FETCH(pThis->iRefCount);
+ if(currRefCount == 0) {
+ /* (only) in this case we need to actually destruct the object */
+ if(pThis->len >= CONF_PROP_BUFSIZE)
+ free(pThis->szVal.psz);
+ } else {
+ pThis = NULL; /* tell framework NOT to destructing the object! */
+ }
+ENDobjDestruct(prop)
+
/* set string, we make our own private copy! This MUST only be called BEFORE
* ConstructFinalize()!
*/
@@ -90,10 +106,8 @@ static rsRetVal GetString(prop_t *pThis, uchar **ppsz, int *plen)
ISOBJ_TYPE_assert(pThis, prop);
if(pThis->len < CONF_PROP_BUFSIZE) {
*ppsz = pThis->szVal.sz;
-RUNLOG;
} else {
*ppsz = pThis->szVal.psz;
-RUNLOG;
}
*plen = pThis->len;
ENDfunc
@@ -123,19 +137,53 @@ static rsRetVal AddRef(prop_t *pThis)
}
-/* destructor for the prop object */
-BEGINobjDestruct(prop) /* be sure to specify the object type also in END and CODESTART macros! */
- int currRefCount;
-CODESTARTobjDestruct(prop)
- currRefCount = ATOMIC_DEC_AND_FETCH(pThis->iRefCount);
- if(currRefCount == 0) {
- /* (only) in this case we need to actually destruct the object */
- if(pThis->len >= CONF_PROP_BUFSIZE)
- free(pThis->szVal.psz);
+/* this is a "do it all in one shot" function that creates a new property,
+ * assigns the provided string to it and finalizes the property. Among the
+ * convenience, it is alos (very, very) slightly faster.
+ * rgerhards, 2009-07-01
+ */
+static rsRetVal CreateStringProp(prop_t **ppThis, uchar* psz, int len)
+{
+ DEFiRet;
+ propConstruct(ppThis);
+ SetString(*ppThis, psz, len);
+ propConstructFinalize(*ppThis);
+ RETiRet;
+}
+
+/* another one-stop function, quite useful: it takes a property pointer and
+ * a string. If the string is already contained in the property, nothing happens.
+ * If the string is different (or the pointer NULL), the current property
+ * is destructed and a new one created. This can be used to get a specific
+ * name in those cases where there is a good chance that the property
+ * immediatly previously processed already contained the value we need - in
+ * which case we save us all the creation overhead by just reusing the already
+ * existing property).
+ * rgerhards, 2009-07-01
+ */
+rsRetVal CreateOrReuseStringProp(prop_t **ppThis, uchar *psz, int len)
+{
+ uchar *pszPrev;
+ int lenPrev;
+ DEFiRet;
+ assert(ppThis != NULL);
+
+ if(*ppThis == NULL) {
+ /* we need to create a property */
+ CHKiRet(CreateStringProp(ppThis, psz, len));
} else {
- pThis = NULL; /* tell framework NOT to destructing the object! */
+ /* already exists, check if we can re-use it */
+ GetString(*ppThis, &pszPrev, &lenPrev);
+ if(len != lenPrev && ustrcmp(psz, pszPrev)) {
+ /* different, need to discard old & create new one */
+ propDestruct(ppThis);
+ CHKiRet(CreateStringProp(ppThis, psz, len));
+ } /* else we can re-use the existing one! */
}
-ENDobjDestruct(prop)
+
+finalize_it:
+ RETiRet;
+}
/* debugprint for the prop object */
@@ -167,6 +215,8 @@ CODESTARTobjQueryInterface(prop)
pIf->GetString = GetString;
pIf->GetStringLen = GetStringLen;
pIf->AddRef = AddRef;
+ pIf->CreateStringProp = CreateStringProp;
+ pIf->CreateOrReuseStringProp = CreateOrReuseStringProp;
finalize_it:
ENDobjQueryInterface(prop)
diff --git a/runtime/prop.h b/runtime/prop.h
index 62c0d799..e3519664 100644
--- a/runtime/prop.h
+++ b/runtime/prop.h
@@ -46,6 +46,8 @@ BEGINinterface(prop) /* name must also be changed in ENDinterface macro! */
rsRetVal (*GetString)(prop_t *pThis, uchar** ppsz, int *plen);
int (*GetStringLen)(prop_t *pThis);
rsRetVal (*AddRef)(prop_t *pThis);
+ rsRetVal (*CreateStringProp)(prop_t **ppThis, uchar* psz, int len);
+ rsRetVal (*CreateOrReuseStringProp)(prop_t **ppThis, uchar *psz, int len);
ENDinterface(prop)
#define propCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */