mallocForeignPtr vs. C

Evan Laforge qdunkan at
Mon Jul 12 14:56:11 EDT 2010

So I was planning to pass a StorableVector to C.  StorableVector uses
ForeignPtrs to manage its memory, so it should just be a pointer pass.
 I happily wrote up a reference counting scheme so I could attach
decref to the finalizer and have haskell and C cooperate about when to
delete the pointer.  However, then I found out that StorableVector
uses mallocForeignPtr, which says it already has the equivalent of a
free() finalizer attached, without actually using a finalizer.

So it looks like I can't safely pass it to C unless I also guarantee
that haskell still has a reference to it.  So the only thing I thought
of to deal with that is to pass C a FunPtr to a "wrapper" style
haskell function.  That function is never called, but it returns the
vector so the haskell GC can't free the vector while the function is
still alive.  Then when C is done with the vector, it can call
freeHaskellFunPtr via the usual freeHaskellFunPtr wrapper trick.

But I'm not convinced that's actually enough because the C code is
still running outside of a withForeignPtr.  I would have to do
something really hairy like call back to C from the haskell callback,
wrapping it in withForeignPtr.  Is there a better way to convince the
GC that the pointer should remain alive until I explicitly release it
from C?  The ideal I think would be a ref count that would keep the
pointer alive while >0, that could be decremented from C.

Since one of the advantages of ForeignPtr using types is to pass them
to C, this must be a problem someone has dealt with.  A synchronous
call that uses the foreign pointer temporarily is easy enough via
withForeignPtr, but what about when I want to share ownership with C?

More information about the Glasgow-haskell-users mailing list