Running a "final" finaliser
simonmar at microsoft.com
Mon Dec 22 10:13:42 EST 2003
> Thanks for your reply. I'm afraid it's left me even
> more confused about which way to go with this :-(
> If it's possible that future Haskell FFI's don't guarantee
> that all finalisers are run then this more or less rules
> out the use of the reference counting solution (which
> wasn't particularly attractive anyway because it needs to
> be done in C AFAICS :-). If users who want this behaviour
> are required to code it themselves, it seems to require that
> they maintain a global list of all allocated ForeignPtrs.
> But doing that naively will stop them being garbage collected
> at all, unless it's possible to do something clever using weak
> pointers. Perhaps it is possible (or maybe some tricks at the
> C level could be used) but I think it's a significant extra
> burden for FFI users.
Yes, it would have to be a global list of weak pointers to ForeignPtrs.
This topic has come up before, though not on this list. See this
message, and the rest of the thread:
the thread also moved on to ffi at haskell.org:
and be sure to check out the paper by Hans Boehm referenced in that
message, it's a good summary of the issues involved.
> Also, while we're talking about this, maybe the semantics
> of performGC should be clarified. Does it block until
> all GC (and finalisation of garbage ForeignPtrs) is complete?
> I would guess this was the original intention, but this
> doesn't seem to be consistent with non-stop Haskell. If
> it does block, are all Haskell threads blocked, or just
> the calling thread?
performGC doesn't do anything that you can rely on :-) In practice, it
probably starts all the finalizers that are ready to run, but it
certainly doesn't wait for their termination.
> Also, I could you explain what you mean by a suitable
> exception handler? I don't really understand this at all.
> I'd expected I may well end up using bracket or similar,
> but I'm not sure how exception handling is relevant to
> this problem.
Start your program something like this:
import Control.Exception (finally)
main = my_main `finally` clean_up
my_main = ... put your program here ...
clean_up = ... all the cleanup code goes here ...
You can additionally use finalizers to perform incremental cleanup
during program execution, but the right way to clean up at the end is to
use an exception handler as above.
More information about the Glasgow-haskell-users