From: "Iñaki Baz Castillo" Date: 2012-05-25T18:22:05+09:00 Subject: Re: [C exten] Could Ruby GC my VALUE in while acquiring the GVL? 2012/5/25 Eric Wong : > Iñaki Baz Castillo 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 :) -- Iñaki Baz Castillo