Re: exception trap in key snooper callback




On Aug 4, 2008, at 8:50 PM, Kevin Ryde wrote:

muppet <scott asofyet org> writes:

http://mail.gnome.org/archives/gtk-perl-list/2003-August/ msg00398.html

Sounds pretty fair, though I think key snooper would also be a
"non-immediate" type callback, ie. like a signal emission it comes out
of somewhere deep in g_main_iterate (or whatever). Or alternately think of it as convenience so that (like a signal emit) an error there doesn't
kill the whole main loop.

If that's a reasonable thing, then we'd probably need to invoke the exception trapping magic in a hand-written keysnooper callback wrapper. The important bit is gperl_run_exception_handlers(); the rest is painful boilerplate.


/* UNTESTED CODE */
static gboolean
gtk2perl_key_snooper_func (GtkWidget * grab_widget,
                           GdkEventKey * event,
                           gpointer func_data)
{
        GPerlCallback * callback = func_data;
        gboolean ret = FALSE;
        SV * saved_errsv;
        dGPERL_CALLBACK_MARSHAL_SP;

        GPERL_CALLBACK_MARSHAL_INIT (calback);

        ENTER;
        SAVETMPS;
        PUSHMARK (SP);

        EXTEND (SP, 2);
        PUSHs (sv_2mortal (newSVGtkWidget (grab_widget)));
        PUSHs (sv_2mortal (newSVGdkEvent (event)));
        if (callback->data)
                XPUSHs (sv_2mortal (newSVsv (callback->data)));

        PUTBACK;

        /* save ERRSV so we can restore it before returning. */
        saved_errsv = sv2_mortal (newSVsv (ERRSV));

        /* Invoke in eval context to trap exceptions */
        call_sv (callback_sv, G_SCALAR | G_EVAL);

        SPAGAIN;

        if (SvTRUE (ERRSV)) {
                /* Exception in callback.  Eat it. */
                gperl_run_exception_handlers ();

                /* Clear the undef off the top of the stack */
                POPs;

        } else {
                /* No exception. */
                ret = SvTRUE (POPs);
        }

        /* We modified the stack. */
        PUTBACK;

        /* Undo our save... */
        SvSetSV (ERRSV, saved_errsv);

        FREETMPS;
        LEAVE;

        return ret;
}


you *can* cleanly longjmp() out of most callbacks (or at
least, we haven't seen crashes because of it).

I'd be surprised if a few didn't leak some memory at least though :-)

Undoubtedly. In an exceptional situation, leaking is preferable to crashing. This assumes that you're not simply using exceptions for control flow, in which case, shame on you.


--
Me:  What's that in your mouth?
Zella:  *swallows laboriously*  Nothing.
Me:  What did you just swallow?
Zella:  A booger.
Me:  Baby girl, don't eat boogers.  That's gross.
Zella:  But it was in my nose.




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]