guile-gtk-general
[Top][All Lists]
Advanced

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

Exceptions and GObject-based libraries


From: Andy Wingo
Subject: Exceptions and GObject-based libraries
Date: Fri, 27 Aug 2004 14:08:17 +0100
User-agent: Mutt/1.5.6+20040803i

Ay, messed up the email address...

> From: Andy Wingo <address@hidden>
> Subject: Exceptions and GObject-based libraries
> To: address@hidden
> Cc: address@hidden
> 
> Hey all,
> 
> I've been tracking down bizarre bugs in some code I'm writing. In doing
> so, I realized that my naive practice of throwing exceptions and
> invoking continuations in a signal handler is incorrect.
> 
> The concrete reason is that signal_emit_unlocked_R in gsignal.c
> allocates a data structure on the stack, references it from the heap,
> assuming that it can dereference it when the function exits. If the
> function performs a nonlocal exit, then gsignal.c still points to a
> location on the stack, which will probably be clobbered later as the
> stack grows. (Speaking of emission and g_recursive_emissions.)
> 
> This is unfortunate, and really reduces the expressivity of using
> higher-level languages with gobject-based libraries. I seem to recall
> that python uses different return values to implement exceptions, but I
> know C++ has true non-local exits. I wanted to know how the rest of you
> deal with this situation.
> 
> Also, I wanted to know if there's interest in at least making GObject
> exception-safe. Gtk+ would take a lot more work, of course. This would
> likely require explicit unwind blocks in a function, e.g.:
> 
> int state = 0;
> 
> int
> myfun (void)
> {
>         G_BEGIN_UNWIND_PROTECT (myfun);
> 
>       state = 1;
>       emit_my_signal ();
> 
>       G_UNWIND (myfun) {
>               state = 0;
>       }
> 
>         G_END_UNWIND_PROTECT (myfun);
>         return 10;
> }
> 
> The expansion could be something like the following:
> 
> int
> myfun (void)
> {
>         int _myfun_jumped;
>         jmp_buf _myfun_jmp_buf;
>         g_push_jmp_buf (&_myfun_jmp_buf);
> 
>       if ((_myfun_jumped = setjmp (_myfun_jmp_buf)))
>               goto _myfun_unwind;
> 
>       state = 1;
>       emit_my_signal ();
> 
> _myfun_unwind:
>         g_pop_jmp_buf ();
>       {
>               state = 0;
>       }
> 
>         if (_myfun_jumped)
>               longjmp (*g_peek_jmp_buf (), -1);
> 
>         return 10;
> }
> 
> The push/pop routines would have to keep a thread-local stack of jump
> buffers for all of this to work. Then a language binding would have
> to catch any uncaught exceptions coming from closures, call
> `longjmp (g_peek_jmp_buf (), -1)' (which should probably be wrapped as
> g_throw or something), and have a jmp buffer set up to catch uncaught
> exceptions somewhere.
> 
> I'm afraid this is all too complicated, though. Portability would also
> bite us pretty hard. But I see in the future a world in which few people
> write their graphical applications in C. It would be a shame if all of
> these higher-level languages would have to restrict themselves in order
> to use Gtk+.
> 
> Any thoughts? Am I crazy?
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]