From: "Iñaki Baz Castillo" Date: 2012-05-22T09:31:57+09:00 Subject: Re: [C ext and GVL] Why UBF() is called even if Ruby traps signals ?? 2012/5/22 Eric Wong : > Iñaki Baz Castillo wrote: >> After experiments, the ubf() is called in those cases: >> >> 1) The thread running the blocking region is killed with Thread#kill. >> >> 2) An interrupt for which trap(SIGNAL_NAME, "SIG_INT") has NOT been >> set arrives while the process is blocked in the blocking region. If >> the signal has a handler in Ruby land then ubf() is always called( >> regardless the trap handler will terminate the program or not !!!). > > Yes, otherwise for a single-threaded Ruby application, signal handlers > have only one thread to fire in (so it needs to interrupt uv_run()). Therefore I cannot use the ubf() for nothing. Typicall my code will be single thread (see explanation below please). >> Badly, in any of those cases, if >> rb_thread_interrupted(rb_thread_current()) is called within the ubf() >> function it returns false, so honestly I have no idea of  how to react >> when my ubf() is called. If it's due to a signal I want it to be >> treated in Ruby land. If it's a Thread#kill then I need to do my stuff >> within the ubf() function. I see no way. > > With the self-pipe trick, your ubf() will probably just be: > >        /* write one \0 byte */ >        write(pipe_wfd, "", 1); > > Where the other end of that pipe is being watched by uv_run() > (installed like any other IO object you're watching for). 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) 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. 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. Thanks a lot. -- Iñaki Baz Castillo