On Mon, May 21, 2012 at 4:47 PM, Eric Wong <normalperson / yhbt.net> wrote:

> I=F1aki Baz Castillo <ibc / aliax.net> wrote:
> > 2012/5/21 I=F1aki Baz Castillo <ibc / aliax.net>:
> > > - So the problem is that: at this moment I see my_ubf() funcion calle=
d
> > > !!! WHY? If I plan to trap/ignore SIGTERM signal, why is my_ubf()
> > > ALWAYS called? why should I "interrupt my blocking function" (uv_run)
> > > if I don't want since SIGTERM will be ignored in Ruby land?
> >
> > 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()).
>
> Given what you say about uv_run() not being interruptable by signals,
> you should probably use the self-pipe trick documented here:
>   http://cr.yp.to/docs/selfpipe.html
>
> MRI 1.9.3+ itself uses a self-pipe itself, as does unicorn.
>
> > 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).
>
>
Or use pselect(2). Not sure how portable that is though.

Jos
--=20
Jos Backus
jos at catnook.com