[racket] FFI: struct of callbacks vs. GC

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon Nov 12 07:57:17 EST 2012

Callbacks never move, and they correctly deal with movable values
referenced in the closure, so the only issue should be whether the GC
reclaims a cllacbk. It can be tricky to make sure that a callback is
not GCed too early, though.

As a test, you might try specifying `#:keep' as a function that put its
callback argument in a new immobile cell. Assuming that you never free
the cell, then the callback should never get GCed.


At Mon, 12 Nov 2012 01:14:03 -0500, Jon Zeppieri wrote:
> I'm running into a problem using the ffi, and I think it has to do
> with passing a struct containing a number of callbacks to a foreign
> function. The foreign code hangs on to this struct and may invoke the
> callbacks any number of times.
> 
> When the GC runs, things go south quickly. I'm pretty sure the reason
> is that the callbacks are getting moved by the GC, and the foreign
> code is left with a struct full of bad pointers. This seems to be
> confirmed by the ffi docs:
> 
> ===
> Structs are allocated as atomic blocks, which means that the garbage
> collector ignores their content. Thus, struct fields can hold only
> non-pointer values, pointers to memory outside the GC’s control, and
> otherwise-reachable pointers to immobile GC-managed values (such as
> those allocated with malloc and 'internal or 'internal-atomic).
> ===
> 
> I found this old message from Matthew
> [http://lists.racket-lang.org/users/archive/2010-July/040480.html],
> but I think his suggestion to define the callbacks at the module
> top-level only prevents them from being reclaimed, not from being
> moved.
> 
> It seems that I need either an immobile closure pointer or a way of
> sending callbacks to the foreign code without making them invisible to
> the GC.
> 
> Any ideas?
> 
> -Jon
> 
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users


Posted on the users mailing list.