From 4412b88148a21d54ba1c2f88ba894b6223986b9a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 29 Feb 2008 09:14:10 +0000 Subject: changed obj base object's calling interface to use the new obj_if_t interface structure --- action.c | 20 +++++++-- action.h | 1 + ctok.c | 2 +- ctok_token.c | 2 +- debug.c | 21 ++++++++-- expr.c | 2 +- msg.c | 6 +-- obj-types.h | 34 ++++++++++------ obj.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- obj.h | 50 +++++++++++++++-------- queue.c | 31 +++++++------- stream.c | 8 ++-- syslogd.c | 5 ++- sysvar.c | 2 +- var.c | 5 ++- vm.c | 2 +- vmop.c | 2 +- vmprg.c | 2 +- vmstk.c | 2 +- wti.c | 3 +- wtp.c | 3 +- 21 files changed, 246 insertions(+), 87 deletions(-) diff --git a/action.c b/action.c index 25821c46..2580c2ac 100644 --- a/action.c +++ b/action.c @@ -41,11 +41,11 @@ #include "cfsysline.h" #include "srUtils.h" - /* forward definitions */ rsRetVal actionCallDoAction(action_t *pAction, msg_t *pMsg); /* object static data (once for all instances) */ +DEFobjStaticHelpers static int glbliActionResumeInterval = 30; int glbliActionResumeRetryCount = 0; /* how often should suspended actions be retried? */ @@ -202,7 +202,7 @@ actionConstructFinalize(action_t *pThis) * spec. -- rgerhards, 2008-01-30 */ CHKiRet(queueConstruct(&pThis->pQueue, ActionQueType, 1, iActionQueueSize, (rsRetVal (*)(void*,void*))actionCallDoAction)); - objSetName((obj_t*) pThis->pQueue, pszQName); + obj.SetName((obj_t*) pThis->pQueue, pszQName); /* ... set some properties ... */ # define setQPROP(func, directive, data) \ @@ -675,6 +675,18 @@ finalize_it: } -/* - * vi:set ai: +/* TODO: we are not yet a real object, the ClassInit here just looks like it is.. + */ +rsRetVal actionClassInit(void) +{ + DEFiRet; + /* request objects we use */ + CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ + +finalize_it: + RETiRet; +} + + +/* vi:set ai: */ diff --git a/action.h b/action.h index 09a3616b..ac65e459 100644 --- a/action.h +++ b/action.h @@ -79,6 +79,7 @@ rsRetVal actionSetGlobalResumeInterval(int iNewVal); rsRetVal actionDoAction(action_t *pAction); rsRetVal actionCallAction(action_t *pAction, msg_t *pMsg); rsRetVal actionWriteToAction(action_t *pAction); +rsRetVal actionClassInit(void); #if 1 #define actionIsSuspended(pThis) ((pThis)->bSuspended == 1) diff --git a/ctok.c b/ctok.c index b10001f2..867a448f 100644 --- a/ctok.c +++ b/ctok.c @@ -587,7 +587,7 @@ ENDobjQueryInterface(ctok) -BEGINObjClassInit(ctok, 1) /* class, version */ +BEGINObjClassInit(ctok, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(ctok_token)); CHKiRet(objUse(var)); diff --git a/ctok_token.c b/ctok_token.c index 13a39a54..fa21d12c 100644 --- a/ctok_token.c +++ b/ctok_token.c @@ -119,7 +119,7 @@ finalize_it: ENDobjQueryInterface(ctok_token) -BEGINObjClassInit(ctok_token, 1) /* class, version */ +BEGINObjClassInit(ctok_token, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(var)); diff --git a/debug.c b/debug.c index 4272f9d6..a13f7e61 100644 --- a/debug.c +++ b/debug.c @@ -51,7 +51,8 @@ /* static data (some time to be replaced) */ -int Debug; /* debug flag - read-only after startup */ +DEFobjCurrIf(obj) +int Debug; /* debug flag - read-only after startup */ int debugging_on = 0; /* read-only, except on sig USR1 */ static int bLogFuncFlow = 0; /* shall the function entry and exit be logged to the debug log? */ static int bLogAllocFree = 0; /* shall calls to (m/c)alloc and free be logged to the debug log? */ @@ -800,8 +801,8 @@ dbgoprint(obj_t *pObj, char *fmt, ...) if(altdbg != NULL) fprintf(altdbg, "%s: ", pszThrdName); /* print object name header if we have an object */ if(pObj != NULL) { - if(stddbg != NULL) fprintf(stddbg, "%s: ", objGetName(pObj)); - if(altdbg != NULL) fprintf(altdbg, "%s: ", objGetName(pObj)); + if(stddbg != NULL) fprintf(stddbg, "%s: ", obj.GetName(pObj)); + if(altdbg != NULL) fprintf(altdbg, "%s: ", obj.GetName(pObj)); } } bWasNL = (*(fmt + strlen(fmt) - 1) == '\n') ? 1 : 0; @@ -1183,15 +1184,25 @@ dbgGetRuntimeOptions(void) } } + /* end support system to set debug options at runtime */ rsRetVal dbgClassInit(void) { + DEFiRet; + struct sigaction sigAct; sigset_t sigSet; (void) pthread_key_create(&keyCallStack, dbgCallStackDestruct); /* MUST be the first action done! */ + + /* while we try not to use any of the real rsyslog code (to avoid infinite loops), we + * need to have the ability to query object names. Thus, we need to obtain a pointer to + * the object interface. -- rgerhards, 2008-02-29 + */ + CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ + memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = sigusr2Hdlr; @@ -1212,7 +1223,9 @@ rsRetVal dbgClassInit(void) } dbgSetThrdName((uchar*)"main thread"); - return RS_RET_OK; + +finalize_it: + RETiRet; } diff --git a/expr.c b/expr.c index ec96b187..a6b24c88 100644 --- a/expr.c +++ b/expr.c @@ -406,7 +406,7 @@ ENDobjQueryInterface(expr) * before anything else is called inside this class. * rgerhards, 2008-02-19 */ -BEGINObjClassInit(expr, 1) /* class, version */ +BEGINObjClassInit(expr, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(vmprg)); CHKiRet(objUse(var)); diff --git a/msg.c b/msg.c index b2ea1870..029dc70c 100644 --- a/msg.c +++ b/msg.c @@ -393,7 +393,7 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm) assert(pThis != NULL); assert(pStrm != NULL); - CHKiRet(objBeginSerialize(pStrm, (obj_t*) pThis)); + CHKiRet(obj.BeginSerialize(pStrm, (obj_t*) pThis)); objSerializeSCALAR(pStrm, iProtocolVersion, SHORT); objSerializeSCALAR(pStrm, iSeverity, SHORT); objSerializeSCALAR(pStrm, iFacility, SHORT); @@ -413,7 +413,7 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm) objSerializePTR(pStrm, pCSPROCID, CSTR); objSerializePTR(pStrm, pCSMSGID, CSTR); - CHKiRet(objEndSerialize(pStrm)); + CHKiRet(obj.EndSerialize(pStrm)); finalize_it: RETiRet; @@ -2200,7 +2200,7 @@ MsgGetSeverity(obj_t *pThis, int *piSeverity) * before anything else is called inside this class. * rgerhards, 2008-01-04 */ -BEGINObjClassInit(msg, 1) +BEGINObjClassInit(msg, 1, OBJ_IS_CORE_MODULE) /* request objects we use */ CHKiRet(objUse(var)); diff --git a/obj-types.h b/obj-types.h index 79781e44..23c2d761 100644 --- a/obj-types.h +++ b/obj-types.h @@ -60,9 +60,10 @@ typedef enum { /* IDs of known object "types/classes" */ OBJvm = 11, OBJsysvar = 12, OBJvmstk = 13, - OBJexpr = 14 /* remeber to UPDATE OBJ_NUM_IDS (below) if you add one! */ + OBJobj = 14, /* the base object itself - somewhat tricky, but required... */ + OBJexpr = 15 /* remeber to UPDATE OBJ_NUM_IDS (below) if you add one! */ } objID_t; -#define OBJ_NUM_IDS 15 +#define OBJ_NUM_IDS 16 typedef enum { /* IDs of base methods supported by all objects - used for jump table, so * they must start at zero and be incremented. -- rgerahrds, 2008-01-04 @@ -156,15 +157,24 @@ typedef struct obj { /* the dummy struct that each derived class can be casted t rsRetVal (*Set##prop)(obj##_t *pThis, dataType) /* class initializer */ #define PROTOTYPEObjClassInit(objName) rsRetVal objName##ClassInit(void) -#define BEGINObjClassInit(objName, objVers) \ +/* below: objName must be the object name (e.g. vm, strm, ...) and ISCORE must be + * 1 if the module is a statically linked core module and 0 if it is a + * dynamically loaded one. -- rgerhards, 2008-02-29 + */ +#define OBJ_IS_CORE_MODULE 1 +#define OBJ_IS_LOADABLE_MODULE 0 +#define BEGINObjClassInit(objName, objVers, objType) \ rsRetVal objName##ClassInit(void) \ { \ DEFiRet; \ - CHKiRet(objInfoConstruct(&pObjInfoOBJ, OBJ##objName, (uchar*) #objName, objVers, \ + if(objType == OBJ_IS_CORE_MODULE) { \ + CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ \ + } \ + CHKiRet(obj.InfoConstruct(&pObjInfoOBJ, OBJ##objName, (uchar*) #objName, objVers, \ (rsRetVal (*)(void*))objName##Construct, (rsRetVal (*)(void*))objName##Destruct)); #define ENDObjClassInit(objName) \ - objRegisterObj(OBJ##objName, pObjInfoOBJ); \ + obj.RegisterObj(OBJ##objName, pObjInfoOBJ); \ finalize_it: \ RETiRet; \ } @@ -220,25 +230,25 @@ finalize_it: \ * processing. * rgerhards, 2008-01-30 */ -#define BEGINobjDestruct(obj) \ - rsRetVal obj##Destruct(obj##_t **ppThis) \ +#define BEGINobjDestruct(OBJ) \ + rsRetVal OBJ##Destruct(OBJ##_t **ppThis) \ { \ DEFiRet; \ int iCancelStateSave; \ - obj##_t *pThis; + OBJ##_t *pThis; -#define CODESTARTobjDestruct(obj) \ +#define CODESTARTobjDestruct(OBJ) \ ASSERT(ppThis != NULL); \ pThis = *ppThis; \ - ISOBJ_TYPE_assert(pThis, obj); \ + ISOBJ_TYPE_assert(pThis, OBJ); \ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); -#define ENDobjDestruct(obj) \ +#define ENDobjDestruct(OBJ) \ goto finalize_it; /* prevent compiler warning ;) */ \ /* no more code here! */ \ finalize_it: \ if(pThis != NULL) { \ - objDestructObjSelf((obj_t*) pThis); \ + obj.DestructObjSelf((obj_t*) pThis); \ free(pThis); \ *ppThis = NULL; \ } \ diff --git a/obj.c b/obj.c index c18bdd4d..01694d41 100644 --- a/obj.c +++ b/obj.c @@ -3,6 +3,41 @@ * This file implements a generic object "class". All other classes can * use the service of this base class here to include auto-destruction and * other capabilities in a generic manner. + * + * As of 2008-02-29, I (rgerhards) am adding support for dynamically loadable + * objects. In essence, each object will soon be available via its interface, + * only. Before any object's code is accessed (including global static methods), + * the caller needs to obtain an object interface. To do so, it needs to provide + * the object name and the file where the object is expected to reside in. A + * file may not be given, in which case the object is expected to reside in + * the rsyslog core. The caller than receives an interface pointer which can + * be utilized to access all the object's methods. This method enables rsyslog + * to load library modules on demand. In order to keep overhead low, callers + * should request object interface only once in the object Init function and + * free them when they exit. The only exception is when a caller needs to + * access an object only conditional, in which case a pointer to its interface + * shall be aquired as need first arises but still be released only on exit + * or when there definitely is no further need. The whole idea is to limit + * the very performance-intense act of dynamically loading an objects library. + * Of course, it is possible to violate this suggestion, but than you should + * have very good reasoning to do so. + * + * Please note that there is one trick we need to do. Each object queries + * the object interfaces and it does so via objUse(). objUse, however, is + * part of the obj object's interface (implemented via the file you are + * just reading). So in order to obtain a pointer to objUse, we need to + * call it - obviously not possible. One solution would be that objUse is + * hardcoded into all callers. That, however, would bring us into slight + * trouble with actually dynamically loaded modules, as we should NOT + * rely on the OS loader to resolve symbols back to the caller (this + * is a feature not universally available and highly importable). Of course, + * we can solve this with a pHostQueryEtryPoint() call. It still sounds + * somewhat unnatural to call a regular interface function via a special + * method. So what we do instead is define a special function called + * objGetObjInterface() which delivers our own interface. That function + * than will be defined global and be queriable via pHostQueryEtryPoint(). + * I agree, technically this is much the same, but from an architecture + * point of view it looks cleaner (at least to me). * * File begun on 2008-01-04 by RGerhards * @@ -75,8 +110,9 @@ static rsRetVal objInfoNotImplementedDummy(void __attribute__((unused)) *pThis) * objects, thus they are in the parameter list. * pszName must point to constant pool memory. It is never freed. */ -rsRetVal objInfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, int iObjVers, - rsRetVal (*pConstruct)(void *), rsRetVal (*pDestruct)(void *)) +static rsRetVal +InfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, int iObjVers, + rsRetVal (*pConstruct)(void *), rsRetVal (*pDestruct)(void *)) { DEFiRet; int i; @@ -106,7 +142,8 @@ finalize_it: /* set a method handler */ -rsRetVal objInfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void*)) +static rsRetVal +InfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void*)) { assert(pThis != NULL); assert(objMethod > 0 && objMethod < OBJ_NUM_METHODS); @@ -118,8 +155,8 @@ rsRetVal objInfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pH /* destruct the base object properties. * rgerhards, 2008-01-29 */ -rsRetVal -objDestructObjSelf(obj_t *pThis) +static rsRetVal +DestructObjSelf(obj_t *pThis) { DEFiRet; @@ -175,7 +212,8 @@ finalize_it: /* begin serialization of an object * rgerhards, 2008-01-06 */ -rsRetVal objBeginSerialize(strm_t *pStrm, obj_t *pObj) +static rsRetVal +BeginSerialize(strm_t *pStrm, obj_t *pObj) { DEFiRet; @@ -199,7 +237,8 @@ finalize_it: * Otherwise, the serialization is exactly the same. * rgerhards, 2008-01-11 */ -rsRetVal objBeginSerializePropBag(strm_t *pStrm, obj_t *pObj) +static rsRetVal +BeginSerializePropBag(strm_t *pStrm, obj_t *pObj) { DEFiRet; @@ -216,7 +255,8 @@ finalize_it: /* append a property */ -rsRetVal objSerializeProp(strm_t *pStrm, uchar *pszPropName, propType_t propType, void *pUsr) +static rsRetVal +SerializeProp(strm_t *pStrm, uchar *pszPropName, propType_t propType, void *pUsr) { DEFiRet; uchar *pszBuf = NULL; @@ -324,7 +364,8 @@ finalize_it: /* end serialization of an object. The caller receives a * standard C string, which he must free when no longer needed. */ -rsRetVal objEndSerialize(strm_t *pStrm) +static rsRetVal +EndSerialize(strm_t *pStrm) { DEFiRet; @@ -657,7 +698,8 @@ finalize_it: * The caller must destruct the created object. * rgerhards, 2008-01-07 */ -rsRetVal objDeserialize(void *ppObj, objID_t objTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t*,void*), void *pUsr) +static rsRetVal +Deserialize(void *ppObj, objID_t objTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t*,void*), void *pUsr) { DEFiRet; rsRetVal iRetLocal; @@ -715,7 +757,8 @@ finalize_it: /* De-Serialize an object, but treat it as property bag. * rgerhards, 2008-01-11 */ -rsRetVal objDeserializeObjAsPropBag(obj_t *pObj, strm_t *pStrm) +rsRetVal +objDeserializeObjAsPropBag(obj_t *pObj, strm_t *pStrm) { DEFiRet; rsRetVal iRetLocal; @@ -760,7 +803,8 @@ finalize_it: * The caller must destruct the created object. * rgerhards, 2008-01-07 */ -rsRetVal objDeserializePropBag(obj_t *pObj, strm_t *pStrm) +static rsRetVal +DeserializePropBag(obj_t *pObj, strm_t *pStrm) { DEFiRet; rsRetVal iRetLocal; @@ -805,8 +849,8 @@ finalize_it: * rgerhards, 2008-01-29 * TODO: change the naming to a rsCStr obj! (faster) */ -rsRetVal -objSetName(obj_t *pThis, uchar *pszName) +static rsRetVal +SetName(obj_t *pThis, uchar *pszName) { DEFiRet; @@ -829,8 +873,8 @@ finalize_it: * is returned. * rgerhards, 2008-01-30 */ -uchar * -objGetName(obj_t *pThis) +static uchar * +GetName(obj_t *pThis) { uchar *ret; uchar szName[128]; @@ -840,7 +884,7 @@ objGetName(obj_t *pThis) if(pThis->pszName == NULL) { snprintf((char*)szName, sizeof(szName)/sizeof(uchar), "%s %p", objGetClassName(pThis), pThis); - objSetName(pThis, szName); + SetName(pThis, szName); /* looks strange, but we NEED to re-check because if there was an * error in objSetName(), the pointer may still be NULL */ @@ -862,7 +906,8 @@ objGetName(obj_t *pThis) * (e.g. for de-serialization support). * rgerhards, 2008-01-07 */ -rsRetVal objRegisterObj(objID_t oID, objInfo_t *pInfo) +static rsRetVal +RegisterObj(objID_t oID, objInfo_t *pInfo) { DEFiRet; @@ -878,6 +923,55 @@ finalize_it: } +/* queryInterface function + * rgerhards, 2008-02-29 + */ +BEGINobjQueryInterface(obj) +CODESTARTobjQueryInterface(obj) + if(pIf->ifVersion != objCURR_IF_VERSION) { /* check for current version, increment on each change */ + ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); + } + + /* ok, we have the right interface, so let's fill it + * Please note that we may also do some backwards-compatibility + * work here (if we can support an older interface version - that, + * of course, also affects the "if" above). + */ + pIf->oID = OBJobj; + + pIf->InfoConstruct = InfoConstruct; + pIf->DestructObjSelf = DestructObjSelf; + pIf->BeginSerializePropBag = BeginSerializePropBag; + pIf->InfoSetMethod = InfoSetMethod; + pIf->BeginSerialize = BeginSerialize; + pIf->SerializeProp = SerializeProp; + pIf->EndSerialize = EndSerialize; + pIf->RegisterObj = RegisterObj; + pIf->Deserialize = Deserialize; + pIf->DeserializePropBag = DeserializePropBag; + pIf->SetName = SetName; + pIf->GetName = GetName; +finalize_it: +ENDobjQueryInterface(obj) + + +/* This function returns a pointer to our own interface. It is used as the + * hook that every object (including dynamically loaded ones) can use to + * obtain a pointer to our interface which than can be used to obtain + * pointers to any other interface in the system. This function must be + * externally visible because of its special nature. + * rgerhards, 2008-02-29 [nice - will have that date the next time in 4 years ;)] + */ +rsRetVal +objGetObjInterface(obj_if_t *pIf) +{ + DEFiRet; + assert(pIf != NULL); + objQueryInterface(pIf); + RETiRet; +} + + /* initialize our own class */ rsRetVal objClassInit(void) diff --git a/obj.h b/obj.h index b73dff11..cf5aed6a 100644 --- a/obj.h +++ b/obj.h @@ -61,12 +61,16 @@ } #define objSerializeSCALAR_VAR(strm, propName, propType, var) \ - CHKiRet(objSerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) &var)); + CHKiRet(obj.SerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) &var)); #define objSerializeSCALAR(strm, propName, propType) \ - CHKiRet(objSerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) &pThis->propName)); + CHKiRet(obj.SerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) &pThis->propName)); #define objSerializePTR(strm, propName, propType) \ - CHKiRet(objSerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) pThis->propName)); -#define DEFobjStaticHelpers static objInfo_t *pObjInfoOBJ = NULL; + CHKiRet(obj.SerializeProp(strm, (uchar*) #propName, PROPTYPE_##propType, (void*) pThis->propName)); +#define DEFobjStaticHelpers \ + static objInfo_t *pObjInfoOBJ = NULL; \ + DEFobjCurrIf(obj) + + #define objGetClassName(pThis) (((obj_t*) (pThis))->pObjInfo->pszName) #define objGetObjID(pThis) (((obj_t*) (pThis))->pObjInfo->objID) #define objGetVersion(pThis) (((obj_t*) (pThis))->pObjInfo->iObjVers) @@ -85,21 +89,33 @@ #define objDebugPrint(pThis) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_DEBUGPRINT])(pThis) #define OBJSetMethodHandler(methodID, pHdlr) \ - CHKiRet(objInfoSetMethod(pObjInfoOBJ, methodID, (rsRetVal (*)(void*)) pHdlr)) + CHKiRet(obj.InfoSetMethod(pObjInfoOBJ, methodID, (rsRetVal (*)(void*)) pHdlr)) + +/* interfaces */ +BEGINinterface(obj) /* name must also be changed in ENDinterface macro! */ + rsRetVal (*UseObj)(uchar *pObjName, uchar *pObjFile, interface_t **ppIf); + rsRetVal (*InfoConstruct)(objInfo_t **ppThis, objID_t objID, uchar *pszName, int iObjVers, + rsRetVal (*pConstruct)(void *), rsRetVal (*pDestruct)(void *)); + rsRetVal (*DestructObjSelf)(obj_t *pThis); + rsRetVal (*BeginSerializePropBag)(strm_t *pStrm, obj_t *pObj); + rsRetVal (*InfoSetMethod)(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void*)); + rsRetVal (*BeginSerialize)(strm_t *pStrm, obj_t *pObj); + rsRetVal (*SerializeProp)(strm_t *pStrm, uchar *pszPropName, propType_t propType, void *pUsr); + rsRetVal (*EndSerialize)(strm_t *pStrm); + rsRetVal (*RegisterObj)(objID_t oID, objInfo_t *pInfo); + rsRetVal (*Deserialize)(void *ppObj, objID_t objTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t*,void*), void *pUsr); + rsRetVal (*DeserializePropBag)(obj_t *pObj, strm_t *pStrm); + rsRetVal (*SetName)(obj_t *pThis, uchar *pszName); + uchar * (*GetName)(obj_t *pThis); +ENDinterface(obj) +#define objCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ + /* prototypes */ -rsRetVal objInfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, int iObjVers, rsRetVal (*pConstruct)(void *), rsRetVal (*pDestruct)(void *)); -rsRetVal objDestructObjSelf(obj_t *pThis); -rsRetVal objInfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void*)); -rsRetVal objBeginSerializePropBag(strm_t *pStrm, obj_t *pObj); -rsRetVal objBeginSerialize(strm_t *pStrm, obj_t *pObj); -rsRetVal objSerializeProp(strm_t *pStrm, uchar *pszPropName, propType_t propType, void *pUsr); -rsRetVal objEndSerialize(strm_t *pStrm); -rsRetVal objRegisterObj(objID_t oID, objInfo_t *pInfo); -rsRetVal objDeserialize(void *ppObj, objID_t objTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t*,void*), void *pUsr); -rsRetVal objDeserializePropBag(obj_t *pObj, strm_t *pStrm); -rsRetVal objSetName(obj_t *pThis, uchar *pszName); -uchar * objGetName(obj_t *pThis); +/* the following define *is* necessary, because it provides the root way of obtaining + * interfaces (at some place we need to start our query... + */ +rsRetVal objGetObjInterface(obj_if_t *pIf); PROTOTYPEObjClassInit(obj); #endif /* #ifndef OBJ_H_INCLUDED */ diff --git a/queue.c b/queue.c index 1020dfcc..a6bcff9f 100644 --- a/queue.c +++ b/queue.c @@ -253,8 +253,8 @@ queueStartDA(queue_t *pThis) CHKiRet(queueConstruct(&pThis->pqDA, QUEUETYPE_DISK , 1, 0, pThis->pConsumer)); /* give it a name */ - snprintf((char*) pszDAQName, sizeof(pszDAQName)/sizeof(uchar), "%s[DA]", objGetName((obj_t*) pThis)); - objSetName((obj_t*) pThis->pqDA, pszDAQName); + snprintf((char*) pszDAQName, sizeof(pszDAQName)/sizeof(uchar), "%s[DA]", obj.GetName((obj_t*) pThis)); + obj.SetName((obj_t*) pThis->pqDA, pszDAQName); /* as the created queue is the same object class, we take the * liberty to access its properties directly. @@ -337,7 +337,7 @@ queueInitDA(queue_t *pThis, int bEnqOnly, int bLockMutex) * rgerhards, 2008-01-24 */ if(pThis->pWtpDA == NULL) { - lenBuf = snprintf((char*)pszBuf, sizeof(pszBuf), "%s:DA", objGetName((obj_t*) pThis)); + lenBuf = snprintf((char*)pszBuf, sizeof(pszBuf), "%s:DA", obj.GetName((obj_t*) pThis)); CHKiRet(wtpConstruct (&pThis->pWtpDA)); CHKiRet(wtpSetDbgHdr (pThis->pWtpDA, pszBuf, lenBuf)); CHKiRet(wtpSetpfChkStopWrkr (pThis->pWtpDA, (rsRetVal (*)(void *pUsr, int)) queueChkStopWrkrDA)); @@ -720,7 +720,7 @@ queueTryLoadPersistedInfo(queue_t *pThis) CHKiRet(strmConstructFinalize(psQIF)); /* first, we try to read the property bag for ourselfs */ - CHKiRet(objDeserializePropBag((obj_t*) pThis, psQIF)); + CHKiRet(obj.DeserializePropBag((obj_t*) pThis, psQIF)); /* then the ungotten object queue */ iUngottenObjs = pThis->iUngottenObjs; @@ -728,15 +728,15 @@ queueTryLoadPersistedInfo(queue_t *pThis) while(iUngottenObjs > 0) { /* fill the queue from disk */ - CHKiRet(objDeserialize((void*) &pUsr, OBJmsg, psQIF, NULL, NULL)); + CHKiRet(obj.Deserialize((void*) &pUsr, OBJmsg, psQIF, NULL, NULL)); queueUngetObj(pThis, pUsr, MUTEX_ALREADY_LOCKED); --iUngottenObjs; /* one less */ } /* and now the stream objects (some order as when persisted!) */ - CHKiRet(objDeserialize(&pThis->tVars.disk.pWrite, OBJstrm, psQIF, + CHKiRet(obj.Deserialize(&pThis->tVars.disk.pWrite, OBJstrm, psQIF, (rsRetVal(*)(obj_t*,void*))queueLoadPersStrmInfoFixup, pThis)); - CHKiRet(objDeserialize(&pThis->tVars.disk.pRead, OBJstrm, psQIF, + CHKiRet(obj.Deserialize(&pThis->tVars.disk.pRead, OBJstrm, psQIF, (rsRetVal(*)(obj_t*,void*))queueLoadPersStrmInfoFixup, pThis)); CHKiRet(strmSeekCurrOffs(pThis->tVars.disk.pWrite)); @@ -861,7 +861,7 @@ static rsRetVal qDelDisk(queue_t *pThis, void **ppUsr) int64 offsOut; CHKiRet(strmGetCurrOffset(pThis->tVars.disk.pRead, &offsIn)); - CHKiRet(objDeserialize(ppUsr, OBJmsg, pThis->tVars.disk.pRead, NULL, NULL)); + CHKiRet(obj.Deserialize(ppUsr, OBJmsg, pThis->tVars.disk.pRead, NULL, NULL)); CHKiRet(strmGetCurrOffset(pThis->tVars.disk.pRead, &offsOut)); /* This time it is a bit tricky: we free disk space only upon file deletion. So we need @@ -935,7 +935,7 @@ queueUngetObj(queue_t *pThis, obj_t *pUsr, int bLockMutex) ISOBJ_TYPE_assert(pThis, queue); ISOBJ_assert(pUsr); /* TODO: we aborted right at this place at least once -- race? 2008-02-28 */ - dbgoprint((obj_t*) pThis, "ungetting user object %s\n", objGetName(pUsr)); + dbgoprint((obj_t*) pThis, "ungetting user object %s\n", obj.GetName(pUsr)); BEGIN_MTX_PROTECTED_OPERATIONS(pThis->mut, bLockMutex); iRet = queueAddLinkedList(&pThis->pUngetRoot, &pThis->pUngetLast, pUsr); ++pThis->iUngottenObjs; /* indicate one more */ @@ -962,7 +962,7 @@ queueGetUngottenObj(queue_t *pThis, obj_t **ppUsr) iRet = queueDelLinkedList(&pThis->pUngetRoot, &pThis->pUngetLast, ppUsr); --pThis->iUngottenObjs; /* indicate one less */ - dbgoprint((obj_t*) pThis, "dequeued ungotten user object %s\n", objGetName(*ppUsr)); + dbgoprint((obj_t*) pThis, "dequeued ungotten user object %s\n", obj.GetName(*ppUsr)); RETiRet; } @@ -1652,7 +1652,7 @@ rsRetVal queueStart(queue_t *pThis) /* this is the ConstructionFinalizer */ /* create worker thread pools for regular operation. The DA pool is created on an as-needed * basis, which potentially means never under most circumstances. */ - lenBuf = snprintf((char*)pszBuf, sizeof(pszBuf), "%s:Reg", objGetName((obj_t*) pThis)); + lenBuf = snprintf((char*)pszBuf, sizeof(pszBuf), "%s:Reg", obj.GetName((obj_t*) pThis)); CHKiRet(wtpConstruct (&pThis->pWtpReg)); CHKiRet(wtpSetDbgHdr (pThis->pWtpReg, pszBuf, lenBuf)); CHKiRet(wtpSetpfChkStopWrkr (pThis->pWtpReg, (rsRetVal (*)(void *pUsr, int)) queueChkStopWrkrReg)); @@ -1759,12 +1759,12 @@ static rsRetVal queuePersist(queue_t *pThis, int bIsCheckpoint) * queue is re-created. Well, we'll also save the current queue type, just so that * we know when somebody has changed the queue type... -- rgerhards, 2008-01-11 */ - CHKiRet(objBeginSerializePropBag(psQIF, (obj_t*) pThis)); + CHKiRet(obj.BeginSerializePropBag(psQIF, (obj_t*) pThis)); objSerializeSCALAR(psQIF, iQueueSize, INT); objSerializeSCALAR(psQIF, iUngottenObjs, INT); objSerializeSCALAR(psQIF, tVars.disk.sizeOnDisk, INT64); objSerializeSCALAR(psQIF, tVars.disk.bytesRead, INT64); - CHKiRet(objEndSerialize(psQIF)); + CHKiRet(obj.EndSerialize(psQIF)); /* now we must persist all objects on the ungotten queue - they can not go to * to the regular files. -- rgerhards, 2008-01-29 @@ -2110,7 +2110,10 @@ finalize_it: * before anything else is called inside this class. * rgerhards, 2008-01-09 */ -BEGINObjClassInit(queue, 1) +BEGINObjClassInit(queue, 1, OBJ_IS_CORE_MODULE) + /* request objects we use */ + + /* now set our own handlers */ OBJSetMethodHandler(objMethod_SETPROPERTY, queueSetProperty); ENDObjClassInit(queue) diff --git a/stream.c b/stream.c index 9f2f06c6..35b38c5e 100644 --- a/stream.c +++ b/stream.c @@ -774,7 +774,7 @@ rsRetVal strmSerialize(strm_t *pThis, strm_t *pStrm) ISOBJ_TYPE_assert(pStrm, strm); strmFlush(pThis); - CHKiRet(objBeginSerialize(pStrm, (obj_t*) pThis)); + CHKiRet(obj.BeginSerialize(pStrm, (obj_t*) pThis)); objSerializeSCALAR(pStrm, iCurrFNum, INT); objSerializePTR(pStrm, pszFName, PSZ); @@ -793,7 +793,7 @@ rsRetVal strmSerialize(strm_t *pThis, strm_t *pStrm) l = (long) pThis->iCurrOffs; objSerializeSCALAR_VAR(pStrm, iCurrOffs, LONG, l); - CHKiRet(objEndSerialize(pStrm)); + CHKiRet(obj.EndSerialize(pStrm)); finalize_it: RETiRet; @@ -888,7 +888,9 @@ strmGetCurrOffset(strm_t *pThis, int64 *pOffs) * before anything else is called inside this class. * rgerhards, 2008-01-09 */ -BEGINObjClassInit(strm, 1) +BEGINObjClassInit(strm, 1, OBJ_IS_CORE_MODULE) + /* request objects we use */ + OBJSetMethodHandler(objMethod_SERIALIZE, strmSerialize); OBJSetMethodHandler(objMethod_SETPROPERTY, strmSetProperty); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, strmConstructFinalize); diff --git a/syslogd.c b/syslogd.c index 506f90a8..2f7ba0f2 100644 --- a/syslogd.c +++ b/syslogd.c @@ -178,6 +178,7 @@ #include "sysvar.h" /* definitions for objects we access */ +DEFobjCurrIf(obj) DEFobjCurrIf(expr) DEFobjCurrIf(vm) @@ -2900,7 +2901,7 @@ init(void) exit(1); } /* name our main queue object (it's not fatal if it fails...) */ - objSetName((obj_t*) pMsgQueue, (uchar*) "main queue"); + obj.SetName((obj_t*) pMsgQueue, (uchar*) "main queue"); /* ... set some properties ... */ # define setQPROP(func, directive, data) \ @@ -3577,6 +3578,7 @@ static rsRetVal InitGlobalClasses(void) CHKiRet(objClassInit()); /* *THIS* *MUST* always be the first class initilizer being called! */ /* dummy "classes" */ CHKiRet(confClassInit()); + CHKiRet(actionClassInit()); /* real ones */ CHKiRet(msgClassInit()); @@ -3595,6 +3597,7 @@ static rsRetVal InitGlobalClasses(void) CHKiRet(exprClassInit()); /* request objects we use */ + CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ CHKiRet(objUse(expr)); CHKiRet(objUse(vm)); diff --git a/sysvar.c b/sysvar.c index c532c4dd..aafcb688 100644 --- a/sysvar.c +++ b/sysvar.c @@ -186,7 +186,7 @@ ENDobjQueryInterface(sysvar) * before anything else is called inside this class. * rgerhards, 2008-02-19 */ -BEGINObjClassInit(sysvar, 1) /* class, version */ +BEGINObjClassInit(sysvar, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(var)); diff --git a/var.c b/var.c index 9cd070a3..aa2100b4 100644 --- a/var.c +++ b/var.c @@ -387,7 +387,10 @@ ENDobjQueryInterface(var) * before anything else is called inside this class. * rgerhards, 2008-02-19 */ -BEGINObjClassInit(var, 1) /* class, version */ +BEGINObjClassInit(var, 1, OBJ_IS_CORE_MODULE) /* class, version */ + /* request objects we use */ + + /* now set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, varDebugPrint); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, varConstructFinalize); ENDObjClassInit(var) diff --git a/vm.c b/vm.c index ab919e17..5c0eccba 100644 --- a/vm.c +++ b/vm.c @@ -522,7 +522,7 @@ ENDobjQueryInterface(vm) * before anything else is called inside this class. * rgerhards, 2008-02-19 */ -BEGINObjClassInit(vm, 1) /* class, version */ +BEGINObjClassInit(vm, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(vmstk)); CHKiRet(objUse(var)); diff --git a/vmop.c b/vmop.c index 8e3ae90c..199ec4cd 100644 --- a/vmop.c +++ b/vmop.c @@ -216,7 +216,7 @@ ENDobjQueryInterface(vmop) * before anything else is called inside this class. * rgerhards, 2008-02-19 */ -BEGINObjClassInit(vmop, 1) /* class, version */ +BEGINObjClassInit(vmop, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(var)); diff --git a/vmprg.c b/vmprg.c index 73b4fda0..dde899ad 100644 --- a/vmprg.c +++ b/vmprg.c @@ -161,7 +161,7 @@ ENDobjQueryInterface(vmprg) * before anything else is called inside this class. * rgerhards, 2008-02-19 */ -BEGINObjClassInit(vmprg, 1) /* class, version */ +BEGINObjClassInit(vmprg, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(vmop)); diff --git a/vmstk.c b/vmstk.c index a739f395..3f07a8f4 100644 --- a/vmstk.c +++ b/vmstk.c @@ -222,7 +222,7 @@ ENDobjQueryInterface(vmstk) * before anything else is called inside this class. * rgerhards, 2008-02-19 */ -BEGINObjClassInit(vmstk, 1) /* class, version */ +BEGINObjClassInit(vmstk, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(var)); diff --git a/wti.c b/wti.c index e7120f8a..fab52327 100644 --- a/wti.c +++ b/wti.c @@ -457,7 +457,8 @@ finalize_it: * before anything else is called inside this class. * rgerhards, 2008-01-09 */ -BEGINObjClassInit(wti, 1) /* one is the object version (most important for persisting) */ +BEGINObjClassInit(wti, 1, OBJ_IS_CORE_MODULE) /* one is the object version (most important for persisting) */ + /* request objects we use */ ENDObjClassInit(wti) /* diff --git a/wtp.c b/wtp.c index c68a1e92..6094d469 100644 --- a/wtp.c +++ b/wtp.c @@ -608,7 +608,8 @@ finalize_it: * before anything else is called inside this class. * rgerhards, 2008-01-09 */ -BEGINObjClassInit(wtp, 1) +BEGINObjClassInit(wtp, 1, OBJ_IS_CORE_MODULE) + /* request objects we use */ ENDObjClassInit(wtp) /* -- cgit