[plt-scheme] FFI - garbage collection

From: Yoav Goldberg (yoav.goldberg at gmail.com)
Date: Tue Oct 11 21:05:27 EDT 2005

Hi.
I am wrapping a dll using the v299 ffi.
As a part of my code, I have a c function that returns a pointer to a structure:

(define-syntax defmshare
  (syntax-rules ()
     ((defmshare scheme-name libname type ...)
      (define scheme-name (get-ffi-obj libname mshare (type ...))))))

(defmshare MidiNewEv* "MidiNewEv" _fun _short -> _TMidiEv-pointer)

and I also have a wrapper function to initialize the returned struct
to some default values:

(provide (rename MidiNewEv midi-new-ev))
(define MidiNewEv ;; make sure chan/port/date are initialized to a default
  (lambda (type)
    (let ((ev (MidiNewEv* type)))
      (chan! ev 0)
      (port! ev 0)
      (date! ev 0)
      ev)))

I want to make sure the memory allocated by the "MidiNewEv" function
will be freed by GC,  and from what I understand, I need to use
"register-finalizaer", like so:

(defmshare MidiFreeEv "MidiFreeEv" _fun _TMidiEv-pointer -> _TMidiEv-pointer)

(define MidiNewEv ;; make sure chan/port/date are initialized to a default
  (lambda (type)
    (let ((ev (MidiNewEv* type)))
      (chan! ev 0)
      (port! ev 0)
      (date! ev 0)
      (register-finalizer ev MidiFreeEv)
      ev)))

I hope I got it right until now, let me know if I got something wrong.

But now comes the trickey part.

There is another C function:
(defmshare MidiSendIm "MidiSendIm" _fun _short _TMidiEv-pointer -> _void)

Which FREES any _TMidiEv-pointer passed to it.

As far as I understand this is a problem, since that pointer is still
registered with the finalizer for GC!

How can I fix this? Is there a way to "un-register" a finalizer, so
that I could do something like:
(define GoodMidiSendIm
   (lambda (n ev)
        (unregister-finalizer ev) (MidiSendIm n ev)))
??

Thanks,
Yoav


Posted on the users mailing list.