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