What is the meaning of rb_thread_interrupted()?

Hi, I'm coding a Ruby C extension and would like to know the meaning
of rb_thread_interrupted() function defined in thread.c, whose
content is:

/* This function can be called in blocking region. */
int
rb_thread_interrupted(VALUE thval)
{
    rb_thread_t *th;
    GetThreadPtr(thval, th);
    return RUBY_VM_INTERRUPTED(th);
}

And RUBY_VM_INTERRUPTED(th) is defined as:

#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)

So, when does rb_thread_interrupted() return 1 or 0?

Thanks a lot.

···

--
Iñaki Baz Castillo
<ibc@aliax.net>

Hi, I'm coding a Ruby C extension and would like to know the meaning
of rb_thread_interrupted() function defined in thread.c, whose
content is:

The best way to know the meaning of a function is often to see how it's
used in existing code.

And RUBY_VM_INTERRUPTED(th) is defined as:

#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)

So, when does rb_thread_interrupted() return 1 or 0?

See when Ruby sets the 0x02 bit on th->interrupt_flag and work backwards
from there.

For navigating/learning codebases, I always use (exuberant-)ctags,
(git) grep, and sometimes cflow.

(I could answer your questions directly, but I'd rather teach you how to
be a better fisherman (or source diver :)).

···

Iñaki Baz Castillo <ibc@aliax.net> wrote:

Eric Wong писал 29.04.2012 12:02:

···

Iñaki Baz Castillo <ibc@aliax.net> wrote:

Hi, I'm coding a Ruby C extension and would like to know the meaning
of rb_thread_interrupted() function defined in thread.c, whose
content is:

The best way to know the meaning of a function is often to see how it's
used in existing code.

And RUBY_VM_INTERRUPTED(th) is defined as:

#define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)

So, when does rb_thread_interrupted() return 1 or 0?

See when Ruby sets the 0x02 bit on th->interrupt_flag and work backwards
from there.

For navigating/learning codebases, I always use (exuberant-)ctags,
(git) grep, and sometimes cflow.

(I could answer your questions directly, but I'd rather teach you how to
be a better fisherman (or source diver :)).

Try Ruby Cross Reference -- it uses ctags inside and has full-text search.

    http://rxr.whitequark.org/

--
   WBR, Peter Zotov.

(warning: I don't like using websites in general :slight_smile:

Accessing the source code directly is much more helpful IMNSHO. Iñaki
can easily change the code locally, and run it to see how it behaves and
whether or not it matches his assumptions (based on just reading code).
He can also utilize tracing tools when he's building/running it.

···

Peter Zotov <whitequark@whitequark.org> wrote:

Eric Wong писал 29.04.2012 12:02:
>(I could answer your questions directly, but I'd rather teach you
>how to
>be a better fisherman (or source diver :)).

Try Ruby Cross Reference -- it uses ctags inside and has full-text
search.

   http://rxr.whitequark.org/

Hi both, thanks a lot. I really appreciate the help of Eric and, for
sure, he is 200% right. But being honest, the HTTP link provided by
Peter is useful (until I dominate the world with console tools that
examinate

About my specific question: I couldn't find a good usage example code
of rb_thread_interrupted(). I found it in io.c but that is very very
complex code (at least for me).

Well, let me explain what I want to achieve:

I'm coding a Ruby event library "framework" (like EventMachine) using
libuv. It creates a C loop (uv_loop) that handles events. For entering
into the C loop I call it with rb_thread_call_without_gvl(), and when
some event takes place, I execute the associated Ruby callback by
calling it with rb_thread_call_with_gvl(). It works, so I can run
other Ruby threads at the same time.

Now I want to handle received signals. And I *already* have the needed
code to make it to work perfectly, no issues at all, but maybe it's
not the mos efficient solution:

In the uv_loop I add a "uv_prepare" event which is a callback to be
executed before each loop iteration. In this callback I call to:

    rb_thread_call_with_gvl(rb_thread_check_ints, NULL);

So if a signal has been received, then let Ruby land to handle it (for
example the user could use Ruby trap(){ } method to handle it).

The exact code is here:

  AsyncEngine/ext/asyncengine/asyncengine_ruby.c at master · ibc/AsyncEngine · GitHub

As said before, it works "perfectly" (no issues found for now), but in
case I add (for example) a periodic timer to be executed every 1
miliseconds by UV, then such a callback is executed every 1
milisecond, which involves calling to
"rb_thread_call_with_gvl(rb_thread_check_ints, NULL);".
Maybe it is not efficient and I could check in some other way whether
there are received signals before calling to rb_thread_check_ints() ?

Initially I figured out that rb_thread_interrupted() (which can be
called safely in the blocking region) would be what I'm looking for,
but I think it's not (since it just does not work).

So any help on this "complex" stuf?

Thanks a lot.

···

2012/4/29 Eric Wong <normalperson@yhbt.net>:

Try Ruby Cross Reference -- it uses ctags inside and has full-text
search.

http://rxr.whitequark.org/

(warning: I don't like using websites in general :slight_smile:

Accessing the source code directly is much more helpful IMNSHO. Iñaki
can easily change the code locally, and run it to see how it behaves and
whether or not it matches his assumptions (based on just reading code).
He can also utilize tracing tools when he's building/running it.

--
Iñaki Baz Castillo
<ibc@aliax.net>

I found rb_signal_buff_size() which seems to return the number of
pending signals to handle. I thought that it could help in this way:

static
void prepare_cb(uv_prepare_t* handle, int status)
{
  // Check received interruptions in Ruby land.
  if (rb_signal_buff_size())
    rb_thread_call_with_gvl(rb_thread_check_ints, NULL);

...but it does not because:

1) The process needs to receive two signals instead of one.

2) It does not improve efficience at all (in my benchmarks).

So maybe I should keep the working solution I already have?

Thanks.

···

2012/4/30 Iñaki Baz Castillo <ibc@aliax.net>:

The exact code is here:

AsyncEngine/ext/asyncengine/asyncengine_ruby.c at master · ibc/AsyncEngine · GitHub

As said before, it works "perfectly" (no issues found for now), but in
case I add (for example) a periodic timer to be executed every 1
miliseconds by UV, then such a callback is executed every 1
milisecond, which involves calling to
"rb_thread_call_with_gvl(rb_thread_check_ints, NULL);".
Maybe it is not efficient and I could check in some other way whether
there are received signals before calling to rb_thread_check_ints() ?

Initially I figured out that rb_thread_interrupted() (which can be
called safely in the blocking region) would be what I'm looking for,
but I think it's not (since it just does not work).

--
Iñaki Baz Castillo
<ibc@aliax.net>