General Callback Message Concept
A callback message has the form
typedef struct {
char *class;
/* ... message data ... */
} <message class>;
where class must be the first element and point to a static variable.
Given the following functions dealing with callbacks:
typedef void KillFunc(void *);
typedef int CallbackFunction(Hdb *node, void *msg, void *data);
typedef struct Callback Callback;
InvokeCallback(Hdb *node, void *msg);
Callback *MakeCallback(CallbackFunction *cbFunc, void *data, KillFunc *killFunc);
AppendCallback(Hdb *node, Callback *cb);
PrependCallback(Hdb *node, Callback *cb);
The callbacks are stored as one list per node.
Extract from (sics)hipadaba.h:
typedef struct {
char *class;
SConnection *pCon;
ValueStruct *value;
} SetCallbackMsg;
SetCallbackMsg *SetCallbackCast(void *msg);
The members of callback message contain the additional arguments needed for the handling of
the callback. SetCallbackCast reveals if an anonymous message is a SetCallbackMsg. It returns
NULL otherwise.
Extract from (sics)hipadaba.c:
static char *setCallbackClass="set callback";
SetCallbackMsg *SetCallbackCast(void *msg) {
if (((SetCallbackMsg *)msg)->class == setCallbackClass) {
return msg;
}
return NULL;
}
...
/* calling the callback */
SetCallbackMsg setMsg={setCallbackClass};
setMsg.pCon = pCon;
setMsg.value = value;
InvokeCallback(node, &setMsg);
The text content of setCallbackClass is not very important, it may be used
for logging purposes. The check for a particular class is done by comparing
the pointers, not the contents.
Extract from a module implementing a callback:
int MySetCallback(Hdb *node, void *msg, void *data) {
SetCallbackMsg *setMsg = SetCallbackCast(msg);
MyData *mydata;
if (! setMsg) return 0; /* not handled */
mydata = data;
/* do the set */
return 1;
}
...
void KillMyData(MyData *data) {
/* free resources */
}
...
MyData *data;
Callback *cb;
cb = MakeCallback(MySetCallback, data, (KillFunc *)KillMyData);
AppendCallback(node, cb);
An implementation may use the same callback function for handling different
callback messages, with the same user data:
int CombinedCallback(Hdb *node, void *msg, void *data) {
SetCallbackMsg *setMsg;
UpdateCallbackMsg *updateMsg;
MyData *mydata = data;
setMsg = SetCallbackCast(msg);
if (setMsg) {
/* handle setMsg */
return 1;
}
updateMsg= UpdateCallbackCast(msg);
if (updateMsg) {
/* handle updateMsg */
return 1;
}
return 0; /* not handled */
}
For the implementation of Hipadaba at least the following callbacks have
to be implemented:
- SetCallback
- ReadCallback
- UpdateCallback
- KillForIDCallback
- KillForInternalIDCallback
Printer Friendly
Page Info
This page last changed on 29-Feb-2008 11:54:16 UTC by MarkusZolliker.
|