Peter Zotov
6/14/2009 1:41:00 PM
eden li wrote:
> 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
> }
>
Why do not use ruby array (rb_array_new) as MyOtherStruct?
This may help (just need to keep one object instead of bunch of them...)
--
WBR, Peter Zotov