OK, that test worked. I guess I don't really understand the #:keep documentation. For the default case of #t, it reads "#t — the callback stays in memory as long as the converted Racket function is reachable." What is the "converted Racket function"? I was ignoring "converted," I think, mainly because I'm not sure what distinction is being drawn here, if not between the Racket function and the callback.
I mean that I was counting on the reachability of the Racket function guaranteeing the reachability of the callback. Are there three objects in play here: the Racket function, the converted Racket function, and the callback? Thanks for your help. -Jon On Mon, Nov 12, 2012 at 7:57 AM, Matthew Flatt <mfl...@cs.utah.edu> wrote: > 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 ____________________ Racket Users list: http://lists.racket-lang.org/users