XS, Advanced XS Callback Patch For OCI, Part VIII Just a little 'c'

Just a quick one tonight's installment for my new chapter in XS Fun just looking at the next function from my patch.

Now just to continue on to the next logical step we will need a disable function as well so my patch is


++static void disable_ha( imp_dbh_t *imp_dbh) {

++  sword status;
++    ha_callback_t haevents;
++    haevents.function = NULL;
++    haevents.dbh_ref = NULL;
++    OCIAttrSet_log_stat(imp_dbh->envhp, (ub4) OCI_HTYPE_ENV,NULL ,(ub4)0,(ub4)OCI_ATTR_EVTCBK, imp_dbh->errhp, status);
++	OCIAttrSet_log_stat(imp_dbh->envhp, OCI_HTYPE_ENV,haevents,0,OCI_ATTR_EVTCTX, imp_dbh->errhp , status);

++    return;

static void disable_taf(
    imp_dbh_t *imp_dbh) {

so here we have a 'void' function, one that does not return anything, that simply cleans up some memory on the Oracle side of things as we are cleaning up our FAN callback basically by sending NULL over to Oracle for the values that we actully have not set up yet.

Unlike TAF, FAN callbacks require us to set up two attributes on the Oracle side to make it work. In OCI the process of setting attributes on the server s DBD::Oracle is a simple call to one OCI function 'OCIAttrSet' now the original programmers of DBD::Oracle where smart and, for lack of a better term, 'overloaded' this function with the ' OCIAttrSet_log_stat' which does some nice logging for us and once you start on any OCI project you will appreciate this logging, so thought-out DBD::Oracle this is the function call (well macro really ) that we use.

So first we see that good old sword status; again as the OCIAttrSet_log_stat need it to work. Next we create a version of the 'ha_callback_t' struct we added to the dbdImpl.h file earlier on, and we set the two values we store in that struct to NULL.

Now I make two calls using 'OCIAttrSet_log_stat' in the first one I am passing along a pointer to which Oracle handle I want to store the value, in this case it is the pointer to envhp' which is the Current Oracle Environment, there are many on these Environment, Server, Session etc, if you look at the first few lines of the 'imp_dbh_st' you will see most of them

    OCIEnv 	*envhp;		/* copy of drh pointer	*/
    OCIError 	*errhp;
    OCIServer 	*srvhp;
    OCISvcCtx 	*svchp;
    OCISession	*seshp;

Next because 'c' isn't really that smart I have to tell OCI what type of handle it is and in this case it is a '(ub4) OCI_HTYPE_ENV', now ub4 is just an OCI type of very large unsigned integer and the 'OCI_HTYPE_ENV' is just a constant label for the I think '1' if you really want you can look that up in 'OCI.h' file.

Now the next is a pointer to the value we are going the set and in this case it is 'NULL', next is the size of the value we are pointing to which is of course '0', note that if you stick NULL here it will most likely error as NULL in 'c' is not the same as '0',

Next we give the type of attribute being set and in this case it is 'OCI_ATTR_EVTCBK' which is the pointer to the callback function and finally we send a pointer to our DBD::Oracle error handler and an empty status.

Now the line is another call to OCIAttrSet_log_stat this time we are sending a pointer to our NULL version of the 'ha_callback_t' struct 'haevents' to 'OCI_ATTR_EVTCTX'. Now this is the pointer to the 'Context' of our callback function. For now I will skip over what context means for this this callback so I can explain that in more detail later without getting to far off track here.

Now as a side note I could just send NULL to this value but that could cause a memory leak in Oracle as we would be just setting the pointer to null not the values of the original structure we set along.

So these tow call should clean up any loose memory on the Oracle environment site though it is sometimes very hard to tell just how much memory this does clean up as OCI does do some garbage collection of its own but it is always better to be on the safe side with dealing with 'c' and OCI.

Finally as this is a void function I simply 'return'


As a side try entering 'OCI_ATTR_EVTCTX' in Google or Bing you will be surprised by the results.

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations