summaryrefslogtreecommitdiffstats
path: root/obj.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-02-29 09:14:10 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-02-29 09:14:10 +0000
commit4412b88148a21d54ba1c2f88ba894b6223986b9a (patch)
tree07c18ea553bf5060d2ca1b431164d5a36b725d73 /obj.c
parent3d0f49a82e46fdffd8bb2c653ccb46ddd516e112 (diff)
downloadrsyslog-4412b88148a21d54ba1c2f88ba894b6223986b9a.tar.gz
rsyslog-4412b88148a21d54ba1c2f88ba894b6223986b9a.tar.xz
rsyslog-4412b88148a21d54ba1c2f88ba894b6223986b9a.zip
changed obj base object's calling interface to use the new obj_if_t
interface structure
Diffstat (limited to 'obj.c')
-rw-r--r--obj.c130
1 files changed, 112 insertions, 18 deletions
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)