Alastair Reid alastair at
Wed Sep 25 07:49:17 EDT 2002

> However, to provide a general ordering property on finalizers would
> be quite awkward in GHC - I just can't think of an easy way to do
> it.  [Awkward ways deleted]

If I understand correctly, the problem is that each FP has a cloud of
finalizer objects attached to it with no particular structure between
finalizer objects and the reason for this unstructured cloud is because
you're piggy-backing on some other mechanism.

It seems like the easy way to fix this is not to impose structure on
the cloud but to impose structure on the finalizer objects.  That is,
allow finalizer objects to contain a list of finalizers and then
allocate just one.

Sketch of possible implementation:

  // Some useful support code - nothing exciting

  type Finalizer a = FunPtr (Ptr a -> IO ())
  foreign import "dynamic" invoke_finalizer :: Finalizer -> IO ()

  finalize :: IORef [Finalizer a] -> IO ()
  finalize fs_ref = do
    fs <- readIORef fs_ref
    mapM_ invoke_finalizer fs

  // New implementation built on top of the old implementation

  data NewFP a = NFP (ForeignPtr a) (IORef [Finalizer a])

  newFP :: Ptr a -> Finalizer a -> IO (NewFP a)
  newFP p f = do
    x <- newForeignPtr p (finalize fs_ref)   // old version with Haskell finalizers
    fs_ref <- newIORef [f]
    return (NFP x fs_ref)

  addFPFinalizer :: NewFP a -> Finalizer a -> IO ()
  addFPFinalizer (NFP x fs_ref) f = do
    fs <- readIORef fs_ref
    writeIORef fs_ref (f:fs)


More information about the FFI mailing list