[gambit-list] References between 'foreign' objects.

Estevo euccastro at yahoo.com
Sat Mar 24 16:21:33 EDT 2012


On 2012-03-24, at 12:31 PM, Estevo wrote:
>
>> I still have the somewhat converse problem: when Gambit loses sight of your last Scheme reference to a "parent" struct, it will clean it up even if there are Scheme references to "child" structs.
>> 
>> I would like to somehow make a Scheme reference to the "parent" struct from the "child" structs, so that children will keep the parent alive as long as they are around.  This reference needs not be visible from Scheme; it's only to help the garbage collector do the right thing.
>> 
>> I can think of a couple ways to do this, but they either complicate my macro considerably, or make things more cumbersome for the user -- or both.  I'm asking the list just in case I'm missing an easy way to create these links.
>> 
>
>I haven't looked at the details, but wouldn't a doubly-linked tree work?  In other words, the parent has a list of children, and each child has a "parent" pointer.  Then, whichever node of the tree is being referenced, all of the nodes of the tree will be maintained by the GC.


Thanks for your quick reply!

That wouldn't remove the need for children never to try and deallocate memory.  If I implement a tree but don't prevent children from deallocating their memory, I'll have multiple attempts to free the same memory (and perhaps some attempts to free the addresses of child structs) when the whole tree becomes invisible to Scheme.

And since children won't try to free memory when they go away, there is no point in keeping them alive artificially.

What I'm worried about is not the topology of the graph of references, but what would be the simplest way to implement a single edge, that is, to create a Scheme reference, preferrably without exposing it to the Scheme world.  So far the scheme representations of structs and unions are very thin wrappers on the C data, and I didn't even need conversion code (that is, __BEGIN_CFUN_*** and friends).  I realise I'll have to change that if I want children keeping the parent alive.  I just didn't want to add any more structure than necessary.

My plan, when I asked that question, was to wrap unmanaged objects in a C structure of the form

typedef struct {___SCMOBJ* parent;
                      <actual_struct_type> actual_struct;} <actual_struct_wrapper>;

and add ___BEGIN_(C|S)FUN_*** (etc.) handlers that create the Scheme reference to the parent.  This reference gets deleted in the child's finalizer.

But that looked scary to me.  My current idea is to just map the C struct to a Scheme record with fields 'parent' and 'c-data'.  I'll use conversion to treat the record (and not the c-data field alone) as the Scheme representation of the object, so people won't accidentally hold onto the c-data and lose the record and therefore the reference to the parent.  So the struct finalizer does nothing again; the parent reference gets cleaned up by normal garbage collection of the Scheme record.

If there is nothing very obvious that I'm missing you can safely ignore this question.  The latter option seems good enough to me.  I wouldn't have bothered you with this if I had thought of that one in first place.


Thank you for your time,

Estevo.




More information about the Gambit-list mailing list