
On Tuesday 23 November 2004 13:06, Simon Marlow wrote:
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.
I see.
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.
Autsch. That doesn't sound reasonable indeed. (Though I still have a hard time to believe that there exist no efficient solutions to this problem.)
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
Maybe it can in general. In the example I posted it definitely doesn't. You get the output from the finalizers before the program terminates, which happens only after you hit enter for the second time. If this argument still doesn't convince you, please add the following lines at the end of main, and run again: putStrLn "Program still not terminated, please hit <enter> again!" getChar putStrLn "Program termination will now be initiated." This shouldn't change anything that has been output before ;-) Cheers, Ben -- Top level things with identity are evil. -- Lennart Augustsson