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 !!!
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.
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.
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.
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?
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);
On Thu, Jun 7, 2012 at 4:12 AM, Iñaki Baz C. [email protected] 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.
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
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
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: