Threaded RTS Patch

Manuel M T Chakravarty chak at
Thu Jan 23 21:23:43 EST 2003

[I have redirected this to the FFI list, being our favourite
finalizer battleground]

"Simon Peyton-Jones" <simonpj at> wrote,

> | For now, I resolved the finalizer issue by making the finalizers
> behave
> | approximately as in the non-threaded case.
> | When the main action finishes, all finalizers are run one after
> another
> | (but in unspecified order), then the program exits. While the
> | finalizers are being run, other haskell threads _continue to run_.
> This
> | seems ugly and dangerous to me, but a) it is the same in the
> | non-threaded RTS and b) it's non-trivial to do it differently.
> Hans Boehm (the world expert on this kind of stuff) gave a good talk at
> POPL about finalizers.  His paper "Destructors, finalizers and
> synchronisation" is doubtless somewhere on the web; certainly it's in
> the POPL proceedings.
> He argues strongly that
> 	there should be no system guarantee that 
> 	finalizers are run on program exit
> His main reason is that there can be absolutely no guarantees about
> ordering, so even if the finalizer wants to print something out, for
> example, the stdout handle might have been closed.  Finalizers that just
> close open file handles aren't much of an improvement: the OS cleans up
> anyway.  Finalizers that do more are hamstrung by not knowing what else
> has been finalized first.
> He argues, too, that the programmer can control this stuff himself, by
> running an explicitly-called clean-up routine to release external
> resources (if that is needed).
> Weak pointers can ensure that this clean-up routine does not keep the
> resource alive.

I haven't read Hans Boehm's paper (but will try to get a
copy once I am off this plane and have a decent Internet
connection again).  While I understand the problems of
running finalizers at program exit, I think the OS plus
explicitly-called-clean-up-routine argument doesn't always
work either.  An explicitly called clean up routine doesn't
help when a program terminates abnormally.  Regarding the
OS, it's fine for classic OS resources, such as file
handles, but when middleware-ish services are involved, they
may not be automatically notified of the demise of a process
by the OS.

I guess, it might be argued that such services, which are
often network-based, need to be able to cope with unexpected
failures etc anyway.  

The point about flushing resources has already been made.
Just to support it with an application.  If I write a log
file in my application, I want all log messages flushed to
disk on termination especially if the program terminates
abnormally (where I haven't got a chance to call the flush
routine explicitly).  Such a flushing function needs to be
extra careful when making use of other resources (which may
or may not have been finalized yet), but I think we should
provide the means to implement it.

However, it may be sufficient to require "best effort"
instead of a guarantee that all finalizers run.  In the case
of clean ups, we can't be definite about what happens in the
case of an unexpected failure anyway, but we might want to
arrange for a good outcome (eg, the log file gets flushed)
whenever possible.


More information about the FFI mailing list