Finalizers etcetera

Simon Peyton-Jones simonpj at microsoft.com
Wed Oct 9 05:02:37 EDT 2002


| > (A mutex lock is required to ensure that the pending queue is not
| > traversed more than once, but that is all I think.)
| 
| I don't understand how this would work in single-threaded systems
(like
| I understand NHC to be).

I haven't been following the details of this discussion, but I think
there may be some confusion.

1.  I think we all now agree that it's easy to arrange to run finalisers
at the end of GC, not during GC, by putting them on a queue and running
them after GC.   But as recently as 27 Sept we didn't agree because when
Ross suggested that a Haskell finaliser could call a C function,
Alastair replied:
| That would have the garbage collector invoking a C function (this is
| ok) which then calls a Haskell function (this is not and the ffi spec
| says not to expect it to work).

Still, I think we now agree that this is fine.

2.  The end of GC is by definition a yield point in the original
program; that is, a point where it is prepared to do GC.

3.  Alastair's point is that a GC-yield point might not be a safe place
to run a finaliser.  His example is:
	the main program maintains a list of active windows in a mutable
location
	the finaliser removes an item from that list
He is absolutely right about this.

4.  I believe that the alternative Alastair advocates is to make
finalisers run in C only.  Why does that solve the problem?  Because
that would force the mutable list of windows (in the example) to be
implemented in C, and that in turn means that manipulating the list is
indivisible.


Conclusion: finalisers in C is simply a way of performing atomic
operations.


The obvious conclusions from this are as follows

a) Haskell finalisers are available on all systems

b) Finalisers can run at any GC point.  The programmer needs to be aware
of this.  Often it does not matter (e.g. calling 'free' to un-malloc
some space) but sometimes it does.

c) On systems (like Hugs and NHC) that have no synchronisation
primitives, you have to roll your own by calling C procedures.


I like this because it exposes what the real issue is without imposing a
single solution.  

Simon






More information about the FFI mailing list