Actually, I believe a better solution to the problem I described is
before returning a VALUE from a C proc to Ruby land, keeps a reference
of it somewhere in Ruby. So the code looks like

VALUE v;
...
v = Data_Wrap_Struct (...);
rb_ivar_set (..., &v);
return v;

So that what you returned, v, is not removed by GC before it's
assigned or referenced in Ruby land.

Does this sound like the right approach?

Thanks,

Benjie



On Mon, Jan 4, 2010 at 9:08 PM, Benjie Chen <benjie / lablife.org> wrote:
> On Mon, Jan 4, 2010 at 7:23 PM, Caleb Clausen <vikkous / gmail.com> wrote:
>
>> Or maybe the token.text is being freed between when the token is
>> created and when it's assigned to a ruby variable? There are no
>> ruby-land references to it or the token which refers to it during that
>> brief time, so if the garbage collector happens to be invoked there...
>> but presumably there is a reference to token somewhere on the c call
>> stack, so that shouldn't be an issue.
>
> Hmm, can you elaborate on where the reference in C is created to
> prevent GC? If you look at the code, it has
>
> RToken *token = ALLOC(RToken);
> token->text = rb_str_new2(tk->text);
> return Data_Wrap_Struct(cToken, &frt_token_mark, &frt_token_free, token);
>
> My question is, where is the reference to the Ruby token object
> created to keep GC from reaping it?
>
> 1. token is a ptr to an allocated memory from ALLOC. Does ALLOC create
> memory pts that keeps reference? I don't believe so, because RToken is
> just a struct, and there's no fancy C++ copy constructors to bump
> references on assignment.
>
> 2. Does Data_Wrap_Struct automatically creates a Ruby object with 1
> reference? Or a new, un-assigned Ruby object w/ reference 0 and
> waiting to be assigned to a Ruby variable or a temporary? In the
> latter case, then we'd have an issue, because if GC runs before any
> assignment, GC would get rid of the token and token->text memory.
>
> Note that I am assuming in Ruby, if I do t = token, then a reference
> to token is created on the assignment and that keeps token->text alive
> as well.
>
>