http://qs321.pair.com?node_id=349346


in reply to callbacks in XS code

From looking at my code and yours it seems that you are missing an SPAGAIN; directive after the perl_call_sv() call.

Here's what I use in DBD::Sybase:

if(imp_dbh->err_handler) { dSP; int retval, count; ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(newSViv(CS_NUMBER(errmsg->msgnumber)))); XPUSHs(sv_2mortal(newSViv(CS_SEVERITY(errmsg->msgnumber)))); XPUSHs(sv_2mortal(newSViv(0))); XPUSHs(sv_2mortal(newSViv(0))); XPUSHs(&sv_undef); XPUSHs(&sv_undef); XPUSHs(sv_2mortal(newSVpv(errmsg->msgstring, 0))); if(imp_dbh->sql) XPUSHs(sv_2mortal(newSVpv(imp_dbh->sql, 0))); else XPUSHs(&sv_undef); XPUSHs(sv_2mortal(newSVpv("client", 0))); PUTBACK; if((count = perl_call_sv(imp_dbh->err_handler, G_SCALAR | G_EV +AL)) != 1) croak("An error handler can't return a LIST."); SPAGAIN; if(SvTRUE(ERRSV)) { POPs; retval = 1; } else { retval = POPi; } PUTBACK; FREETMPS; LEAVE; /* If the called sub returns 0 then ignore this error */ if(retval == 0) return CS_SUCCEED; }
This works fine for me (and I have similar code in Sybase::DBlib and Sybase::CTlib.)

Michael