
On 22 November 2004 17:28, Benjamin Franksen wrote:
I understand that there are situations where finalizers cannot be guaranteed to run: First because of an unconditional termination signal (SIGKILL), second because of circular dependencies resulting in a deadlock.
I don't understand why it is necessary to "performGC" explicitly, in order to run finalizers at *normal* program termination and without a deadlock.
It isn't necessary to performGC explicitly. However, you might be seeing a secondary effect due to Handles being finalised at program termination too - a common problem is writing a finaliser that tries to output something on a Handle, where the Handle gets finalised first. The original finaliser will then deadlock (or in 6.2.2 it'll get a more informative exception). This is because at program termination we just run all the outstanding finalisers without regard to ordering. Ordering is too hard to establish, and would at the least require a full GC before running each finaliser.
BTW, the sensible thing to do in this case would be to throw an exception whenever a deadlock condition is detected. (That is, if it can be detected.)
Yes, GHC does cause exceptions to be raised on deadlock.
However, what I don't understand is why touchForeignPtr is not honored in my example program: Note that the output text lines from the finalizers appear *before* the last action in the program (which is a second getChar). The finalizers *are* called by the GC, and still the order is wrong.
Note that the GC only starts the finaliser thread. The program can still terminate before this thread has run to completion (this is one reason why we say that finalisers don't always run before program termination). You have a point that the documentation is plain wrong. I'll try to fix it up for 6.4, and I think at the same time I'll remove the at-exit finalisation. Cheers, Simon