Could Ruby GC my VALUE in while acquiring the GVL?

Hi, I’m in C land without GVL and give value to a static VALUE
variable defined in my .c file and later I acquire the GVL and want to
use such a VALUE variable:

// GVL release here:

static VALUE my_variable;

my_variable = rb_new_str(“hello”, 5);

rb_thread_call_with_gvl(function_with_gvl, NULL);

and function_with_gvl() does this:

static VALUE function_with_gvl(void)
{
return rb_funcall(myObject, rb_intern(“some_method”), 1, my_variable);
}

So my question is: could Ruby GC my_variable while acquiring the GVL?
should I keep it from GC by using rb_gc_register_address(&my_variable)
?

Thanks a lot.

Iñaki Baz C. [email protected] wrote:

Hi, I’m in C land without GVL and give value to a static VALUE
variable defined in my .c file and later I acquire the GVL and want to
use such a VALUE variable:

// GVL release here:

static VALUE my_variable;

Static variables in C are global to the process and not on the stack,
so yes, all static VALUEs need to be registered with GC
(rb_global_variable/rb_gc_register_address)

my_variable = rb_new_str(“hello”, 5);

rb_str_new() is not safe to call without GVL.

rb_thread_call_with_gvl(function_with_gvl, NULL);

So my question is: could Ruby GC my_variable while acquiring the GVL?
should I keep it from GC by using rb_gc_register_address(&my_variable)

Yeah, Ruby can GC your variables at any time.

Keep in mind rb_global_variable/rb_gc_register_address/rb_new_str/…
all require GVL to function safely (always assume Ruby C API
requires the GVL, only a few C API functions are explicitly marked as
thread-safe).

2012/5/25 Eric W. [email protected]:

Static variables in C are global to the process and not on the stack,
so yes, all static VALUEs need to be registered with GC
(rb_global_variable/rb_gc_register_address)

Clear.

my_variable = rb_new_str(“hello”, 5);

rb_str_new() is not safe to call without GVL.

Sorry, bad example, I don’t do that in my code :wink:

rb_thread_call_with_gvl(function_with_gvl, NULL);

So my question is: could Ruby GC my_variable while acquiring the GVL?
should I keep it from GC by using rb_gc_register_address(&my_variable)

Yeah, Ruby can GC your variables at any time.

But also when I’m in C land? This is, if I have the GVL and I’m in C
land:

  1. I delete a VALUE from a Ruby hash and store it in my_value within
    my C function. Such a VALUE is no longer referenced by Ruby so
    theorically it could be GC’d.

  2. Now, still in C, I call to other function by passing my_value as
    argument.

Please, tell me that my_value CANNOT be GC’d between steps 1 and 2.
Mmmmm, but… if for example I call rb_funcall(GC, start) between
steps 1 and 2? Ok, but the point here is that there are not Ruby
functions that could perform GC stuff between steps 1 and 2, so GC
cannot be invoked, am I right?

Keep in mind rb_global_variable/rb_gc_register_address/rb_new_str/…
all require GVL to function safely (always assume Ruby C API
requires the GVL, only a few C API functions are explicitly marked as
thread-safe).

According to rb_thread_blocking_region() doc in thread.c:

  • Safe C API:
  • * rb_thread_interrupted() - check interrupt flag
    
  • * ruby_xalloc(), ruby_xrealloc(), ruby_xfree() -
    
  •     if they called without GVL, acquire GVL automatically.
    

And I would add another one from thread.c that I use:

int ruby_thread_has_gvl_p(void)

which OBVIOUSLY MUST be thread safe :slight_smile: