This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Guile, C, and Garbage Collection



Daniel R Risacher <risacher@worldnet.att.net> wrote: 

> When I'm writing C libraries for interface to Guile (either as
> wrappers or from scratch), a problem arises, and I'd like someone to
> point out what the correct solution is.
>
> Suppose your C library has data types Foo and Bar.  A Foo can
> contain a pointer to a Bar.  You write the functions
> Clib-make-new-foo, Clib-make-new-bar, and
> Clib-foo-set-pointer-to-bar.
>
> Now suppose one of your users does something like this:
>
> (define toplevelfoo (Clib-make-new-foo))
> (let ((temp-bar (Clib-make-new-bar)))
>      (Clib-foo-set-pointer-to-bar toplevelfoo temp-bar))
> (gc)
>
> Now, the bar you allocated with Clib-make-bar doesn't have any scheme
> references to it any more, so it gets garbage collected, because the 
> garbage collector doesn't know that there is a pointer to it inside
> toplevelfoo.   And the next time the program tries to look for 
> toplevelfoo->bar it will seg fault.
>
> Of course, you can solve this by not freeing the C-bar when the
> Scheme-bar is collected, but that entails a memory leak.
>
> What is the "right way" to solve this dilemma?  Is there one?
>

There are two possible approaches to this, which depend on if
Clib-foo-set-pointer-to-bar stores are reference to the Scheme bar
object, or merely the C object that it wraps. In the first case, you
can just use the scm_protect_object function to protect that Scheme
object from garbage collection until the C code is done with it, at
which point you use scm_unprotect_object. 

However, if C code is only going to be storing the unwrapped object,
you don't want to leak the memory of the non-C part, so you're going
to attach some sort of reference counter to the C object that gets
incremented when it is given to C code, and have your garbage
collection function for the Scheme object take this into account. 

But if you save only the C object, not the Scheme object, and you are
not at liberty to modify the layout of the C object to add a reference
counter, you are probably up the proverbial creek and might want to
rethink the interface.

 - Maciej Stachowiak