Fail: <<loop>> from finalizers and stuff
Dear Foreign Function Interface, why does a program like the following fail with a "<<loop>>" exception (using GHC 6.2 on MacOS X)? -----snip----- import Foreign main = do f <- mkFinPtr finalizer fp <- newForeignPtr f nullPtr putStrLn "Hello World" finalizer ptr = putStrLn ("Finalize "++show ptr++".") foreign import ccall "wrapper" mkFinPtr :: (Ptr () -> IO ()) -> IO (FinalizerPtr ()) -----snap----- Also, does the use of a "wrapper" import constitute a callback from C in the sense of the following statement? "Whether a finalizer may call back into the Haskell system is system dependent. Portable code may not rely on such callbacks." I.e. is the above code non-portable? Why is the ForeignPtr interface constrained to finalizers that are FunPtrs at all? I want to touch a ForeignPtr from another's finalizer to satisfy a liveness dependency (as suggested in the spec). What is the best way to do this? Suppose I have: -----snip----- type Thing = Ptr () type Subthing = Ptr () foreign import ccall "new_thing" newThing :: IO Thing foreign import ccall "new_subthing" newSubthing :: Thing -> IO Subthing -----snap----- I can't do, as I would like: -----snip----- foreign import ccall "del_thing" delThing :: Thing -> IO () foreign import ccall "del_subthing" delSubthing :: Subthing -> IO () main = do p1 <- newThing p2 <- newSubthing p1 fp1 <- newForeignPtr delThing p1 fp2 <- newForeignPtr (\p -> delSubthing p >> touchForeignPtr fp1) p2 {- ...do more funny things... -} -----snap----- So because touchForeignPtr is a Haskell function, I must go through a wrapper. It seems strange to me that the Haskell storage manager would not be able to call Haskell routines as finalizers directly... Assuming that's really the only way to do it, I suppose my code would look like this, correct? -----snip----- foreign import ccall "&del_thing" delThing_p :: FunPtr (Thing -> IO ()) foreign import ccall "del_subthing" delSubthing :: Subthing -> IO () foreign import ccall "wrapper" mkFinPtr :: (Ptr () -> IO ()) -> FunPtr (Ptr () -> IO ()) main = p1 <- new_thing p2 <- new_subthing p1 fp1 <- newForeignPtr delThing_p p1 f <- mkFinPtr (\p -> delSubthing p >> touchForeignPtr fp1) fp2 <- newForeignPtr f p2 {- ...do the funky chicken... -} -----snap----- Thanks in advance, Sven Moritz PS: You're still great! PPS: Do you mind being called fifi? ;-)
participants (1)
-
Sven Moritz Hallberg