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.
--
Iñaki Baz Castillo
<ibc@aliax.net>