views:

197

answers:

1

I have several structs bound with Data_Wrap_Struct to ruby objects and I also supplied mark() and free() functions.

When I manually start the GC or just wait until it jumps in my ruby objects are killed. Nothing new so far.

The strange thing is: When I try to protect these objects with rb_gc_register_address() nothing happens - my objects will still be killed.

I can only prevent the GC from doing that with something like this:

objects = rb_ary_new();
rb_gc_register_address(&objects);
rb_ary_push(objects, data);

Is that the only way and why can't I just use rb_gc_register_address()?

+1  A: 

Glancing at this, it appears that the types all line up (You're getting back VALUEs and passing in the VALUE ptr) so my guess is that the mark operation isn't correctly marking the objects and the sweeping phase is snatching them up.

Perhaps by wrapping the child objects in an array that has a correct marker function you protect your data objects.

It's more a theory than a solid answer, but maybe it's something to start with. :)

No, ironically, back to digging a little too deep into the Ruby GC. Looking to wow some recruiters. :D

-- Edit --

To add onto this, I was just digging in gc.c and on line 1098, the precise test you want to fail is

if (!(p->as.basic.flags & FL_MARK))

So do what you must in your mark function to include in your flags FL_MARK so the sweeper doesn't... um... sweep you.

sam