2012/5/25 Eric Wong <normalperson / yhbt.net>:
> Iaki Baz Castillo <ibc / aliax.net> 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)

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 ;)



>> 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 :)



-- 
Iaki Baz Castillo
<ibc / aliax.net>