Well, in the current version, all of the racket functions corresponding to the callbacks are defined at the module top-level. It's likely that in some previous version, I wasn't holding on to them.
I'm now thinking that the callback issue might be a red herring. Even with the #:keep change the program still crashes about 50% of the time. I'm sure I have some other bug lurking around here... On Nov 12, 2012, at 8:58 AM, Matthew Flatt <[email protected]> wrote: > "Converted Racket function" is meant to be the function that you're > passing to the foreign function. That is, there's no distinction > between "the Racket function" and "the converted Racket function". > I'll work on that phrasing in the docs. > > So, can you say more about why you expect the Racket function to be > retained in your example? > > At Mon, 12 Nov 2012 08:49:44 -0500, Jon Zeppieri wrote: >> 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 <[email protected]> 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

