Running a "final" finaliser

Adrian Hey ahey at
Tue Jan 6 09:12:32 EST 2004


Thanks for that explanation, I see the problem now.

Though to be honest, I'm not convinced that the situation
for Haskell implementations which don't implement pre-emptive
concurrency need be as bad as you suggest. But that's probably
presumptious of me seeing as I know little about the
implementations of either Hugs or nhc (or ghc for that matter:-)

I can see there is a potential problem with single threaded programs
which may never call yield, though even in this situation it I would
think it would be relatively straight forward to have an implicit
yield to finalisers at appropriate points (no partially reduced
thunks in the heap).

But then again, I guess the logic is that since foreign object
finalisers will usually be foreign functions which don't re-enter
Haskell it's probably not worth the effort.

The other thing that strikes me about this is don't we also have
the same potential problem with weak pointer finalisers? Can they
be supported in Haskell without pre-emptive concurrency?

Adrian Hey 

On Monday 05 Jan 2004 4:39 pm, Alastair Reid wrote:
> > > I'm afraid I still don't fully understand why Haskell
> > > finalisers are unsafe or why (if) calling Haskell from a C finaliser
> > > (which then called C land again) would be any safer.
> The FFI standard doesn't say that calling C finalizers is unsafe (which
> would imply that the finalizers potentially do something naughty).  Rather,
> the standard says that finalizers are called in a restricted context in
> which they are not allowed to call back into Haskell.
> The reason that finalizers must be written in C and cannot call into
> Haskell is that it requires pretty much all the machinery needed to
> implement preemptive concurrency (multiple C stacks, context switches,
> etc.) which was felt to be an excessively high burden on a Haskell
> implementation just to let you call C functions.  (Of course, GHC already
> has this machinery which is why they provide enhanced functionality.)
> Why does it require most of the machinery of preemptive concurrency?
> Suppose that a finalizer requires the value of something that is currently
> being evaluated by the main thread.  (This is very common and pretty much
> impossible to reason about in Haskell.  For example, it could be a
> dictionary object or the thunk '(==) dict_Int'.)  The correct thing to do
> if this happens is to block the finalizer, run the main thread until the
> shared thunk is updated with a value, and then restart the finalizer.  To
> block a thread in this way, we have to switch C stacks, perform a context
> switch, etc.  QED.
> --
> Alastair Reid

More information about the Glasgow-haskell-users mailing list