E
eden li
I'm writing a C extension which passes around structs that refer to
Ruby VALUEs. During the course of execution, these VALUEs are
assigned new Ruby strings, hashes or arrays (via the rb_{str,hash,ary)
_new functions) through a series of callbacks. The problem is that it
seems they're getting collected too early before I have a chance to
use the result.
I tried a few things to keep these VALUEs around (including calling
rb_gc_mark directly on these objects), but the only thing that seems
to prevent this early collection is by disabling the GC while my code
is executing.
Is there something I can use to prevent these VALUEs from getting re-
used without resorting to turning off the GC altogether?
Here's some pseudo code to help further illustrate the issue:
typedef struct {
VALUE value;
// some other fields
} MyStruct;
typedef struct {
MyStruct **structs;
} MyOtherStruct;
VALUE my_rb_func(VALUE self) {
MyOtherStruct *other;
Data_Get_Struct(rb_iv_get(self, "@other"), MyOtherStruct, other);
other->structs[0]->value = rb_hash_new();
// This chain will allocate new MyStruct references and assign
// new Ruby objects to MyStruct->value entries. The rb_hash_new()
// won't be affected other than using rb_hash_aset().
start_callback_chain(other);
// without disabling gc, other->structs[0]->value is *not* the
original
// hash this is true even if we don't assign anything to subsequent
// MyStruct->value
}
Ruby VALUEs. During the course of execution, these VALUEs are
assigned new Ruby strings, hashes or arrays (via the rb_{str,hash,ary)
_new functions) through a series of callbacks. The problem is that it
seems they're getting collected too early before I have a chance to
use the result.
I tried a few things to keep these VALUEs around (including calling
rb_gc_mark directly on these objects), but the only thing that seems
to prevent this early collection is by disabling the GC while my code
is executing.
Is there something I can use to prevent these VALUEs from getting re-
used without resorting to turning off the GC altogether?
Here's some pseudo code to help further illustrate the issue:
typedef struct {
VALUE value;
// some other fields
} MyStruct;
typedef struct {
MyStruct **structs;
} MyOtherStruct;
VALUE my_rb_func(VALUE self) {
MyOtherStruct *other;
Data_Get_Struct(rb_iv_get(self, "@other"), MyOtherStruct, other);
other->structs[0]->value = rb_hash_new();
// This chain will allocate new MyStruct references and assign
// new Ruby objects to MyStruct->value entries. The rb_hash_new()
// won't be affected other than using rb_hash_aset().
start_callback_chain(other);
// without disabling gc, other->structs[0]->value is *not* the
original
// hash this is true even if we don't assign anything to subsequent
// MyStruct->value
}