[racket] FFI: struct of callbacks vs. GC
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