Re: [Haskell-cafe] Semantics of ForeignPtr Finalizers

On 6/19/11 3:52 AM, Bas van Dijk wrote:
Hello, I have a question about the semantics of finalizers of ForeignPtrs: If an in scope value has a reference to a ForeignPtr is the foreign object always kept alive, even if that reference is not used? Or do I always need to wrap each computation, which needs to have the foreign object alive, inside withForeignPtr?
I know that the Ptr obtained by withForeignPtr will _not_ keep the foreign object alive (though withForeignPtr itself will be sure to keep it alive until the function using the Ptr exits). For instance, this shows up with ByteStrings if you try to save the Ptr somewhere and then use it after withForeignPtr exits. I believe that ForeignPtr itself does promise to keep the foreign object alive, since it's what holds the finalizers. The documentation claims that the finalizers are run only once the ForeignPtr becomes unreachable, which implies that keeping the ForeignPtr is sufficient to keep the foreign object alive. I haven't used ForeignPtr for truly foreign objects, only for pseudo-foreign objects like ByteString, but in my experience just having the ForeignPtr is enough to keep the target alive. -- Live well, ~wren

On 19 June 2011 14:13, wren ng thornton
The documentation claims that the finalizers are run only once the ForeignPtr becomes unreachable, which implies that keeping the ForeignPtr is sufficient to keep the foreign object alive.
Right, that was also my thinking when designing the usb library. What made me doubt this was the implementation of storable vectors: http://hackage.haskell.org/packages/archive/vector/0.7.1/doc/html/src/Data-V... Note that a storable vector stores both a foreign pointer and a pointer (presumably so that you don't need to add an offset to the pointer, inside the foreign pointer, each time you use it): data Vector a = Vector !(Ptr a) !Int !(ForeignPtr a) Now, if we follow the above semantics we don't need to call withForeignPtr when we need to read the memory because the foreign pointer is referenced by the vector. However the vector library still calls withForeignPtr. For example: basicUnsafeIndexM (Vector p _ fp) i = return . unsafeInlineIO $ withForeignPtr fp $ \_ -> peekElemOff p i So is the withForeignPtr redundant so that this function can be rewritten to just: basicUnsafeIndexM (Vector p _ _) i = return . unsafeInlineIO peekElemOff p i Regards, Bas
participants (2)
-
Bas van Dijk
-
wren ng thornton