RE: [Haskell-cafe] ForeignPtrs with liveness dependencies

On 26 July 2005 11:26, Einar Karttunen wrote:
"Simon Marlow"
writes: You might be able to find more information on this in the mailing list archives. It's true that touchForeignPtr isn't enough to enforce an ordering on the running of finalizers, but it *can* be used to express a liveness relationship between one ForeignPtr and another (ForeignPtr A is alive if ForeignPtr B is alive). This should be enough if you're dealing with pointer relationships between memory objects, for example, where it doesn't matter which one gets freed first when they're both unreferenced.
The order of the cleanup functions is significant in this case, so that does not unfortunately help.
If you really do need ordering, maybe it would be possible to use reference counting in your case?
I ended up using the following design, which seems to work fine: data Foo = Foo (ForeignPtr Foo) (IORef [IO ()]) Each ForeignPtr Foo has a single finalizer which first calls the C-side cleanup function for Foo and then executes all the IO-actions inside the IORef.
Now the association becomes associate (Foo _ ref) bar = atomicModifyIORef ref (\lst -> (touchForeignPtr bar : lst, ()))
Isn't that equivalent to using addForeignPtrFinalizer? I don't think this fixes anything: the finalizer for bar can still run before the finalizer for foo. Cheers, Simon

"Simon Marlow"
Now the association becomes associate (Foo _ ref) bar = atomicModifyIORef ref (\lst -> (touchForeignPtr bar : lst, ()))
Isn't that equivalent to using addForeignPtrFinalizer? I don't think this fixes anything: the finalizer for bar can still run before the finalizer for foo.
foo has a single finalizer which is defined like: fooFinalizer cfoo ref = do cdeleteFoo cfoo vs <- readIORef ref mapM_ (\c -> c) vs and foo is created like createFoo ptr = do ref <- newIORef [] fp <- newForeigPtr ptr (fooFinalizer ptr ref) return (Foo fp ref) As the finalizer of foo references the IORef which contains the list of actions containing the "touchForeignPtr bar" the finalizer of foo is run first. The finalizer to bar should be able to run only when the touchForeignPtr has been executed in the mapM_ which only happens after foo has been cleaned up - if I understand things correctly. - Einar Karttunen
participants (2)
-
Einar Karttunen
-
Simon Marlow