2012/6/7 Iaki Baz Castillo <ibc / aliax.net>:
> Also, I've realized about the following in C code:
>
> int exception_tag;
> VALUE ret;
>
> ret = rb_protect(function, Qnil, &exception_tag);
>
>
> If while function() is being executed (which invokes Ruby land code)
> current thread is killed with Thread#kill, then rb_protect() exits
> with the following ANNOYING data:
>
> exception_tag => int 8
> ret => VALUE FIXNUM 8
>
> If after that I do:
>
> VALUE exception = rb_errinfo();
>
> Then I get VALUE FIXNUM 8. Yes, rb_errinfo() returns FIXNUM 8 !!!


After more tests, this is my conclusion and what I will implement in my C code:


static
VALUE execute_function_with_glv_and_rb_protect(void* function)
{
  int error_tag = 0;
  VALUE ret;

  ret = rb_protect(function, Qnil, &error_tag);

  /*
   * If an exception occurs while in function() it can be due:
   *
   * - An Exception (including SystemExit), this is "rescue-able" via
"rescue Exception"
   *   and will run the "ensure" code if present. In this case
rb_errinfo() gets the
   *   exact Exception object.
   *
   * - A Thread#kill. This is NOT "rescue-able" via "rescue Exception"
but it WILL run
   *   the "ensure" code if present. In this case rb_errinfo() returns
FIXNUM 8 (it maybe
   *   different, no idea).
   *
   * So, check the class of the object returned by rb_errinfo(). If
it's an Exception then
   * store it, release the loop and raise it. Otherwise (Thread#kill)
then don't store the
   * exception returned by rb_errinfo() and just release the loop.
Ruby will do the rest.
   */


Hope I'm right.

-- 
Iaki Baz Castillo
<ibc / aliax.net>