[Haskell-cafe] Re: Haskell FFI and finalizers
Maxime Henrion
mux at FreeBSD.org
Tue Oct 9 11:12:19 EDT 2007
Simon Marlow wrote:
> Maxime Henrion wrote:
> >Stefan O'Rear wrote:
> >>On Thu, Oct 04, 2007 at 12:55:41AM +0200, Maxime Henrion wrote:
> >>>When writing the binding for foo_new(), I need to open a file with
> >>>fopen() to pass it the FILE *. Then I get a struct foo * that I can
> >>>easily associate the the foo_destroy() finalizer. However, when
> >>>finalizing the struct foo * object, I want to also close the FILE *
> >>>handle.
> >>>
> >>>If I write a small C function for doing the finalizer myself, I still
> >>>wouldn't get passed the FILE * to close, only the struct foo * pointer
> >>>which is of no use.
> >>Ah, yes, this does make the situation more interesting.
> >>
> >>Looks like newForeignPtrEnv is maybe what you want?
> >
> >Yeah, this is what I use now. I wrote a player_finalizer() function in
> >C, that takes a FILE * and a pointer to the struct I'm handling, and
> >which just closes the file. I then added these sources to the mix in my
> >.cabal file (with C-Sources, Extra-Includes, etc), and registered this
> >new finalizer using addForeignPtrFinalizerEnv.
> >
> >This makes me want to ask you, what is so bad about Foreign.Concurrent
> >that it should be avoided at almost any cost? It sure is likely to be
> >much slower than just calling a plain C finalizer, but aren't Haskell
> >threads super-cheap anyways?
>
> In GHC ordinary ForeignPtr finalizers are implemented using
> Foreign.Concurrent anyway. It's not so much that Foreign.Concurrent should
> be avoided at all costs, but rather finalizers in general should be
> avoided, especially if you really care about when they run (i.e. bad things
> could happen if they run late or at unpredictable times).
>
> The Haskell code is not run "by the garbage collector", rather the garbage
> collector figures out which finalizers need running and creates a thread to
> run them. It's perfectly safe to have C finalizers that invoke Haskell
> code using GHC, although this is explicitly undefined by the FFI spec.
>
> The reason that Foreign.Concurrent is separate from Foreign.ForeignPtr is
> that it does essentially require concurrency to implement, whereas ordinary
> C finalizers can be run by the GC (although GHC doesn't do it this way).
Thank you for those precisions, Simon. It seems that even if using the
Foreign.Concurrent module isn't a problem per-self, I'd be better off
using a plain C finalizer that I write myself, if only for portability
with other FFI implementations.
Cheers,
Maxime
More information about the Haskell-Cafe
mailing list