On Wed, 2009-03-25 at 12:54 +0000, Simon Marlow wrote:
> Axel Simon wrote:
> > Phew,
> > I think we're doomed. We have many, many little methods that take a
> > user-given function, wrap it into a foreign export wrapper which is
> > freed by using an on-destroy callback to Haskell. These functions are
> > most likely installed into some widgets (or other reference-counted
> > objects) that will be eventually destroyed by the Haskell garbage
> > collector. So, basically, we can't easily change Gtk2Hs. It will involve
> > many modifications. I can understand that not allowing callbacks during
> > GC is a great simplification in the runtime but it seemed to be common
> > practice to free Stable and function pointers from within Haskell using
> > a callback.
> > So, unless I'm wrong on why finalizers call back into Haskell land, then
> > this means that Gtk2Hs is fundamentally broken for the foreseeable future.
> Just to be clear here: we haven't removed any functionality. The old
> Haskell finalizers are still available, just not via the API for C
> finalizers. Take a look at Foreign.Concurrent. If you modify gtk2hs to
> use Foreign.Concurrent.newForeignPtr then it should work with older
> versions of GHC too.
Ok, so ghc allows me to associate a C finalizer or a Haskell finalizer
with a ForeignPtr which, in principle, should be sufficient. However, I
think it's not so easy in Gtk2Hs: We use the standard ForeignPtr to
decrease the reference counts of C objects. Once a ForeignPtr is garbage
collected and the reference of the C object drops to zero, all pointers
within the C object are freed by calling their destructors. Thus, if the
user adds a signal callback, stable pointer to Haskell data or a Haskell
finalizer to a Gtk object, then the decrement of the reference count
will invoke their destructors which at the moment live in Haskell land.
In case the user indeed adds a real finalizer to an object (something we
don't provide at the moment), this would definitely mean executing
In case of merely running destructors (for function closures and stable
pointers), it would be very difficult to associate this Haskell handler
with the original ForeignPtr that pointed to the Gtk object in C land.
Thus, the only way forward I see for us to change all methods that
install (function, stable) pointers to Haskell land in a C object such
that they use the C functions for freeing function/stable pointers,
rather than their Haskell equivalents. Installing a Haskell finalizer in
the C object would still be impossible with this approach.
So, I guess, if we cannot call back to Haskell from a normal from a C
stack that is being built during garbage collection, we have to change
the way we install destructors in Gtk2Hs.