Just for clarification: Is it OK to call freeHaskellFunPtr in the Haskell function pointed to itself, i.e. a kind of "self destruction"? Example: foreign import ccall "wrapper" makeCB :: IO () -> IO (FunPtr (IO ())) ... funPtr <- mfix (\self -> makeCB (do freeHaskellFunPtr self; ...)) <register funPtr somewhere in C land> ... The FFI spec doesn't say anything about this, but it would be very handy if this was allowed, e.g. for one-shot callbacks. After a short look into GHC's and Hugs' RTS I think it is OK for both systems: The thunk/adjustor has always a jump at its end, so free-ing the machine code at the jump destination does no harm. Cheers, S.
This looks fairly delicate and might have consequences for debuggers (which tend to keep things on the stack around after a proper tailcalling implementation (or whatever) would have dumped it). It seems like your example could be handled by calling the free function in the Haskell code that invokes the C code that invokes the callback: foreign import enumThingies :: Thingies -> (FunPtr (Thingy -> IO ())) -> IO () printThingies xs = do cb <- makeCB (\ x -> printThingy xs x) -- <- the callback enumThingies xs cb -- <- the C function freeHaskellFunPtr cb How much worse would it be to write your code in this way? I'd prefer not to commit all future implementations to working a particular way unless there's a compelling need. -- Alastair Sven:
Just for clarification: Is it OK to call freeHaskellFunPtr in the Haskell function pointed to itself, i.e. a kind of "self destruction"? Example:
foreign import ccall "wrapper" makeCB :: IO () -> IO (FunPtr (IO ()))
... funPtr <- mfix (\self -> makeCB (do freeHaskellFunPtr self; ...)) <register funPtr somewhere in C land> ...
The FFI spec doesn't say anything about this, but it would be very handy if this was allowed, e.g. for one-shot callbacks. After a short look into GHC's and Hugs' RTS I think it is OK for both systems: The thunk/adjustor has always a jump at its end, so free-ing the machine code at the jump destination does no harm.
participants (2)
-
Alastair Reid -
Sven Panne