From: Eric Wong Date: 2012-05-22T10:39:49+09:00 Subject: Re: [C ext and GVL] Why UBF() is called even if Ruby traps signals ?? I単aki Baz Castillo wrote: > But that's not my problem. In fact, I have a mechanism to communicate > with UV loop at any time safely from any thread: > > uv_async_send() (thread safe) OK, perfect. You can probably just call in your ubf(), nothing else. > So from the ubf() function I have no problem in telling UV "please do > this now or in your next instant iteration". My problem is: what to > say? > > 1) If ubf() has been called from Thread#kill then I need to run a > function that closes all the active UV handlers so uv_run() exits. Can you run those cleanup handlers in the killer and not the killee? You should Thread#join the killee, and then cleanup in the killer. On the other hand, with uv_async_send(), you can probably avoid Thread#kill entirely. Thread#kill can be dangerous/unreliable, as ensure clauses will still fire, and ensure clauses can be broken, too. > 2) If ubf() has been called due to a signal receipt, I don't want > uv_run() to exit. Instead the signal wakeups the UV loop and generates > an iteration in which I call to rb_check_interrupts() for handling the > signal in Ruby land and I'm happy. But the ubf() has been called !!! > > So the problem is that when a signal is received, it makes the ubf() > function to be called and, at that point, I have no way to know, > within the ubf() function, whether it has been called by Thread#kill > or by a received signal. You're right, there's no way for the ubf() to know why it's called. The purpose of the ubf() is only to wake up a thread and have it reacquire the GVL. That's it. Once a thread reacquires the GVL, it can: - run Ruby signal handlers (automatically done by VM) - die (respond to Thread#kill, again automatically done by VM) - give up the GVL again and resume blocking (your choice)