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] |
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