simonmar at microsoft.com
Fri Nov 8 05:32:20 EST 2002
John Meacham writes:
> this already exists in GHC, a side effect of Weak pointers is
> that they allow finalizers to be assosiated with any value.
> addFinalizer :: key -> IO () -> IO ()
> A specialised version of mkWeakPtr, where the Weak object returned is
> simply thrown away (however the finalizer will be remembered by the
> garbage collector, and will still be run when the key becomes
Ross's proposal provides a subtly different mechanism. In fact, it's a
safe way to use finalizers on arbitrary objects - but the price you pay
is having to explicitly delimit uses of the object from the IO monad.
The key function in the new scheme is withFinalized (or withProxy or
whatever you want to call it):
withFinalized :: Finalized a -> (a -> IO b) -> IO b
which "opens" the object for use, and prevents it from being finalized
until the IO action completes.
The problem with using System.Mem.Weak.addFinalizer to place finalizers
on arbitrary objects is that compiler transformations can alter the
lifetime of the object in ways that you don't expect. This is fine for
the use we originally designed it for, memo tables, but for most other
uses it isn't suitable. The only things that can safely have finalizers
attached are "primitive" objects which are explicitly created in the IO
monad - these objects can't be arbtrarily duplicated by the compiler, so
their lifetime is more predictable. IORefs, MVars, ForeignPtrs and
IOArrays fall into this category.
More information about the FFI