def sleep_and_rescue
begin
sleep
# Rescue ANY kind of exception.
rescue Exception => e
puts "exception rescued: #{e.class}: #{e.message}"
ensure
puts "ensure code..."
end
end
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 !!!
···
2012/6/7 Iñaki Baz Castillo <ibc@aliax.net>:
So, it means that the signal send by Thread#kill is not
"rescue--able", am I right?
As far as rescuing kill, you could open the Thread class and reimplementing kill to throw an exception. There's a piece of me that thinks that's a really bad idea, though.
···
On Jun 7, 2012, at 5:22 AM, Iñaki Baz Castillo <ibc@aliax.net> wrote:
2012/6/7 Iñaki Baz Castillo <ibc@aliax.net>:
So, it means that the signal send by Thread#kill is not
"rescue--able", am I right?
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:
···
2012/6/7 Iñaki 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 !!!
*
* - 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.
*/
Hi Tony, I don't want to use Thread#kill nor Thread#raise. It's just
that I want my application to be ready if the user decides to kill the
thread with Thread#kill.
Regards.
···
2012/6/13 Tony Arcieri <tony.arcieri@gmail.com>:
On Thu, Jun 7, 2012 at 4:12 AM, Iñaki Baz Castillo <ibc@aliax.net> wrote:
So, it means that the signal send by Thread#kill is not
"rescue--able", am I right?
I think that's as it should be. If you want the same thing, but
"rescue-able", why not Thread#raise?
Thanks, but I don't want to redefine the Thread class but just be
ready in case the user of my library calls to Thread#kill in his code.
···
2012/6/7 Jam <jam@jamandbees.net>:
As far as rescuing kill, you could open the Thread class and reimplementing kill to throw an exception. There's a piece of me that thinks that's a really bad idea, though.
In order to re-check this possible "issue", I've reported it in Ruby tracker:
···
2012/6/7 Iñaki Baz Castillo <ibc@aliax.net>:
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).
I've exposed Thread#kill in my library (Celluloid) as a sort of last resort.
As for Thread#raise, I think if you reraise the exception at the end of
your error handler after rescuing Exception when it isn't a StandardError,
you should be good
···
On Tue, Jun 12, 2012 at 3:29 PM, Iñaki Baz Castillo <ibc@aliax.net> wrote:
2012/6/13 Tony Arcieri <tony.arcieri@gmail.com>:
> On Thu, Jun 7, 2012 at 4:12 AM, Iñaki Baz Castillo <ibc@aliax.net> > wrote:
>>
>> So, it means that the signal send by Thread#kill is not
>> "rescue--able", am I right?
>
>
> I think that's as it should be. If you want the same thing, but
> "rescue-able", why not Thread#raise?
Hi Tony, I don't want to use Thread#kill nor Thread#raise. It's just
that I want my application to be ready if the user decides to kill the
thread with Thread#kill.
Hi, could somebody please comment on my question? Summarizing:
int error_tag;
ret = rb_protect(function, data, &error_tag);
// While function() is being executed in Ruby land,
// its thread is killed by other thread via Thread.kill.
// If now I inspect rb_errinfo() it returns Fixnum 8, and
// error_tag it's set to integer 8.
I'm coding my application assuming that, in case rb_errinfo() returns
a Fixnum (instead of a Exception object) then I must assume that its
thread has been killed via Thread#kill. Could somebody confirm whether
this assumption is correct or not?
NOTE: Ruby 1.9.3-p0 MRI.
Thanks a lot.
···
2012/6/11 Iñaki Baz Castillo <ibc@aliax.net>:
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).
In order to re-check this possible "issue", I've reported it in Ruby tracker:
Yes, during the libuv loop execution I execute all the Ruby callbacks
with rb_protect(). If an exception/error occurs then I pass it (the
exception object retrieved via rb_errinfo() function) to the "error
handler" of my library which, in case it's a StandardError it would
call the user provided block (optional) to react on errors. Otherwise
(not a standard error) my library properly releases the libuv loop and
re-raises the captured exception.
The only "problem" is that, as said in my other mails, when the thread
is killed with Thread#kill, rb_errinfo() returns Fixnum(8 =
RUBY_TAG_FATAL) instead of an Exception object, so trying to raise a
Fixnum is not a good idea
And... it seems that all of this is due a bug in Ruby:
I've exposed Thread#kill in my library (Celluloid) as a sort of last resort.
As for Thread#raise, I think if you reraise the exception at the end of your
error handler after rescuing Exception when it isn't a StandardError, you
should be good
Hi, could somebody please comment on my question? Summarizing:
int error_tag;
ret = rb_protect(function, data, &error_tag);
// While function() is being executed in Ruby land,
// its thread is killed by other thread via Thread.kill.
// If now I inspect rb_errinfo() it returns Fixnum 8, and
// error_tag it's set to integer 8.
I'm coding my application assuming that, in case rb_errinfo() returns
a Fixnum (instead of a Exception object) then I must assume that its
thread has been killed via Thread#kill. Could somebody confirm whether
this assumption is correct or not?
/* exception from another thread */
if (th->thrown_errinfo) {
VALUE err = th->thrown_errinfo;
th->thrown_errinfo = 0;
thread_debug("rb_thread_execute_interrupts: %"PRIdVALUE"\n", err);
The only "problem" is that, as said in my other mails, when the thread
is killed with Thread#kill, rb_errinfo() returns Fixnum(8 =
RUBY_TAG_FATAL) instead of an Exception object, so trying to raise a
Fixnum is not a good idea
And... it seems that all of this is due a bug in Ruby: