Guarantees regarding finalizers

Hello, I'm writing a binding to a C library, which requires an explicit cleanup call before program termination. While looking for a way to automatize this, I noticed a discrepancy in the standard library documentation. The Foreign.Concurrent documentation states: "The only guarantee is that the finalizer runs before the program terminates." (http://www.haskell.org/ghc/docs/latest/html/libraries/base/Foreign-Concurren...) On the other hand, the Foreign.ForeignPtr documentation states: "Indeed, there is no guarantee that the finalizer is executed at all; a program may exit with finalizers outstanding." (http://www.haskell.org/ghc/docs/latest/html/libraries/base/Foreign-ForeignPt...) Note that Foreign.Concurrent.newForeignPtr is implemented in GHC as GHC.ForeignPtr.newConcForeignPtr. The newConcForeignPtr comments also state: "There is no guarantee of promptness, and in fact there is no guarantee that the finalizer will eventually run at all." (http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-ForeignPt...) As much as I would like the Foreign.Concurrent guarantee to be true, this seems to me like a documentation bug. Best regards, -- Mietek Bąk

On 26/11/2009 12:41, Mietek Bąk wrote:
I'm writing a binding to a C library, which requires an explicit cleanup call before program termination. While looking for a way to automatize this, I noticed a discrepancy in the standard library documentation.
The Foreign.Concurrent documentation states: "The only guarantee is that the finalizer runs before the program terminates." (http://www.haskell.org/ghc/docs/latest/html/libraries/base/Foreign-Concurren...)
On the other hand, the Foreign.ForeignPtr documentation states: "Indeed, there is no guarantee that the finalizer is executed at all; a program may exit with finalizers outstanding." (http://www.haskell.org/ghc/docs/latest/html/libraries/base/Foreign-ForeignPt...)
Note that Foreign.Concurrent.newForeignPtr is implemented in GHC as GHC.ForeignPtr.newConcForeignPtr. The newConcForeignPtr comments also state: "There is no guarantee of promptness, and in fact there is no guarantee that the finalizer will eventually run at all." (http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-ForeignPt...)
As much as I would like the Foreign.Concurrent guarantee to be true, this seems to me like a documentation bug.
The docs are rather backward. Foreign.ForeignPtr finalizers are guaranteed to run, Foreign.Concurrent finalizers are not. I'll fix the docs, thanks for the report. Cheers, Simon

The docs are rather backward. Foreign.ForeignPtr finalizers are guaranteed to run, Foreign.Concurrent finalizers are not. I'll fix the docs, thanks for the report.
Thanks for the reply. Unfortunately, I'm running into the following error message when trying to use a Foreign.ForeignPtr finalizer: "foo: error: a C finalizer called back into Haskell. This was previously allowed, but is disallowed in GHC 6.10.2 and later. To create finalizers that may call back into Haskll, use Foreign.Concurrent.newForeignPtr instead of Foreign.newForeignPtr." Is there a technical reason why the Foreign.Concurrent finalizers aren't guaranteed to run? Best regards, -- Mietek Bąk

On 01/12/2009 11:25, Mietek Bąk wrote:
The docs are rather backward. Foreign.ForeignPtr finalizers are guaranteed to run, Foreign.Concurrent finalizers are not. I'll fix the docs, thanks for the report.
Thanks for the reply. Unfortunately, I'm running into the following error message when trying to use a Foreign.ForeignPtr finalizer:
"foo: error: a C finalizer called back into Haskell. This was previously allowed, but is disallowed in GHC 6.10.2 and later. To create finalizers that may call back into Haskll, use Foreign.Concurrent.newForeignPtr instead of Foreign.newForeignPtr."
Is there a technical reason why the Foreign.Concurrent finalizers aren't guaranteed to run?
It's hard to make it work reliably, and arguably finalizers shouldn't be used in this way [1]. Haskell finalizers are run in separate threads, but separate threads don't normally prevent the Haskell program from exiting, so there would be an inconsistency if we made a special case for finalizers. Another problem is that you often find you need to express dependencies between finalizers, but that is not supported (the finalizers all run concurrently), and even if it were supported, it would probably be necessary to run the GC repeatedly until we run out of finalizers. Cheers, Simon [1] "Destructors, Finalizers, and Synchronization", Boehm, Hans-J. http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html
participants (2)
-
Mietek Bąk
-
Simon Marlow