RE: [Alastair Reid <alastair@reid-consulting-uk.ltd.uk>] Re: cvs commit: haskell-report/ffi finalizers.txt
Hi Alastair | a comment on SimonM's finalizer document. I decided to comment rather | than edit since my comments require more than tweaking the odd word | here and there. I suggest you edit directly, striving, as Simon did, to be even-handed. I do have one comment on your rejoinders, though: | I don't see how adding concurrency strengthens the argument for | Haskell finalizers. | | Adding mutable Haskell state doesn't seem to strengthen it either. | Indeed, I assume the existence of mutable Haskell state in arguing | against Haskell finalizers. Here I disagree! If you have a concurrent Haskell program, with mutable state and MVars and all, it's entirely likely that you'll have mutable state that reflects the state of the external (e.g. C) world. For example, the GHC I/O library has Haskell I/O handles that reflect the state of the underlying C handle. (For example, they contain some buffered characters as well as a C pointer to the underlying C object.) So the finaliser actually watches to the *Haskell* object; when it becomes unreachable the finaliser should run, and (amongst other things) call a suitable finaliser on the C object. But without access to the Haskell world, the finaliser can't even get hold of the C pointer to finalise! So I believe that for a non-stateful, non-concurrent Haskell program the case for Haskell finalizers is moot, it becomes much more compelling once you have state and concurrency anyway. Furthermore, Haskell finalizers then behave just like threads (which by then exist anyway) and must be treated with exactly the same care, no more and no less. Incidentally, as I understand it, it is common ground that, by scheduling finalizers on an ordinary Hugs thread, Hugs could provide Haskell finalizers exactly as GHC does. (Although that is not what Simon's patch does, I know.) The issue then becomes only one of promptness, as Simon described in the writeup. Am I right about that? Simon
If you have a concurrent Haskell program, with mutable state and MVars and all, it's entirely likely that you'll have mutable state that reflects the state of the external (e.g. C) world. For example, the GHC I/O library has Haskell I/O handles that reflect the state of the underlying C handle.
It sounds like you have Haskell objects that need finalized and that they just happen to contain a C object. For this it seems appropriate to use Weak pointers which provide Haskell finalizers and, indeed, that is what GHC does. I didn't notice any use of ForeignPtrs in the IO Handle implementation.
Incidentally, as I understand it, it is common ground that, by scheduling finalizers on an ordinary Hugs thread, Hugs could provide Haskell finalizers exactly as GHC does. (Although that is not what Simon's patch does, I know.)
It would mean ripping the scheduler apart but yes that could be done.
The issue then becomes only one of promptness, as Simon described in the writeup. Am I right about that?
I think 'starvation' is the better term since the concern is that a single-threaded program will never hit a preemption point so the finalizer will never get to run. That is, 'promptness' implies that the finalizer gets delayed for a small but unknown amount of time while 'starvation' implies that the finalizer is delayed for a large, possibly infinite amount of time. With that change in terminology, I think I can agree that the problem with the easily implemented thread option is starvation. -- Alastair
participants (2)
-
Alastair Reid -
Simon Peyton-Jones