[Top][All Lists]
[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?
>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Exceptions and GObject-based libraries,
Andy Wingo <=