Hi, what I understand (after some useful threads in this mailist)
about rb_gc_register_address() is that it’s only valid for fixed
memory (in the stack). So if for example I have a global/static VALUE
in my MyLibrary_init() function, I should use it to avoid GC (it’s not
referenced by any other Ruby object in Ruby land):
static VALUE string_Via;
void MyLibrary_init(void) {
some_string = rb_str_new2(“HELLO WORLS”);
// If I don't do this, it will be GC'd:
rb_gc_register_address(&some_string);
}
But I cannot use rb_global_variable(), for example, to avoid GC for a
VALUE object passed as function parameter since I’m trying to register
its memory address, which would get invalidated after the function
and when the variable gets out of the Ruby scope.
Ok, it makes sense. But I’ve found a way to make it to work and would
like to share it (to know if it’s a risk or it just works in certain
cases):
struct data_struct {
VALUE data;
int lalala;
long lololo;
}
VALUE MyLibrary_some_method(VALUE self, VALUE data)
{
struct data_struct* my_data_struct = ALLOC(struct data_struct);
my_data_struct->data = data;
// This WONT avoid GC:
// rb_gc_register_address(&data);
// But this WILL avoid GC:
rb_gc_register_address(&(my_data_struct->data));
}
The memory address for which I’m calling rb_register_address() is
allocated by me, and I will not free it for now. And before freeing it
I will call rb_gc_unregister_address(&(my_data_struct->data)), so it
“should” be safe.
So, could somebody confirm me that the above is a correct usage of
rb_gc_register_address()? As said before, in my tests it works (it
avoids GC).
BTW I would also like to know whether both rb_gc_register_address()
and rb_gc_unregister_address() can be called without the GVL.
Really thanks a lot.
PS: I’m already using rb_gc_mark() when the VALUE is attached to the C
struct wrapped within a Ruby object, that’s ok. But I “need” the above
usage for the case of C data holding Ruby objects, without such a C
data being “mapped” to a Ruby object.