[plt-scheme] Memory management and ?custodians

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Mar 3 16:03:50 EST 2010

At Wed, 3 Mar 2010 20:40:09 +0000, Norman Gray wrote:
> I think my question boils down to: how do I (effectively) enforce an
> ordering in the reclamation of (the Scheme_Object* wrappers of) two
> inter-related C objects.
> [...]
> if the librdf_storage object is reclaimed before one of its
> librdf_iterator objects, the library complains.

I don't think you want custodians.

Are you using finalizers to release the wrapped values? If so, the
finalizer for the one to be released first could refer to the one that
should be released last.

Concretely, then, the iterator's finalizer could refer to the storage
object, something like this:

 (define (get-iterator storage)
   (let ([i ....])
     (register-finalizer i (lambda (i)
                              ...
                              ;; result will be ignored, but returning
                              ;; `storage' makes the finalizer keep it:
                              storage))
     i))

Another approach is to register each iterator in the storage object,
perhaps using a weak reference, so that and have the finalizer for a
storage object explicitly release each remaining iterator (canceling
any other associated finalizer) before releasing the storage object.

> [ Parenthetically: I'm slightly surprised that the iterator isn't being freed 
> promptly, as it's inside the equivalent of:
>     (let ((storage (get-storage ...))
>       ; do stuff
>       (let ((iterator (get-iterator storage)))
>         #t)
>       (collect-garbage)
>       ; do more stuff with storage
>       )

Switching to 3m could solve that problem. With CGC, it's easy for a
dead reference to be sitting somewhere that the GC thinks is live.



Posted on the users mailing list.