Proposed change to ForeignPtr
ger at tzi.de
Tue Sep 10 12:26:35 EDT 2002
Malcolm Wallace wrote
> I don't see the problem. The Foogle garbage collector runs separately
> and asynchronously to the Haskell GC. A Foogle object is released
> by the Haskell collector, then at a later moment in time, a Haskell
> object is released by the Foogle collector. Where is the conflict?
Does "at a later moment in time" mean that it is late enough that we can
be sure calling Haskell will be OK?
Look, suppose for simplicity that Foogle implements an identical FFI to
Haskell. So we have
(Haskell ForeignPtr A) == (Foogle StablePtr A)
(Foogle StablePtr A) points to (Foogle ForeignPtr B)
(Foogle ForeignPtr B) == (Haskell StablePtr B)
Haskell frees (Haskell ForeignPtr A) thereby causing the finalizer.
This presumably does the Foogle equivalent of freeStablePtr on A.
This *may* trigger an immediate Foogle garbage collection (I think Foogle's
RTS is within its rights if it does), so that Foogle now wants to finalize
Foogle ForeignPtr B. The Foogle finalizer action for foreignPtr B involves
calling back to Haskell so that (Haskell StablePtr B) can have freeStablePtr
applied to it.
Now is the FFI specification going to guarantee that however quickly the
Foogle garbage collector executes the Haskell finalizer, things will work.
It seems to me the wording suggested does not guarantee this. All it says
that the finaliser cannot portably "call back into the Haskell system". But
when the finaliser provokes an immediate GC which calls back into the
I'm altogether rather puzzled by this notion of FunPtr's which are allowed to
call Haskell back at some times and not others. Nor do I understand how it's
supposed to work, say, on truly parallel Haskell implementations.
> Why do you suggest a need for reference counts? In the absence
> of cycles, surely the existing two garbage collectors (howsoever
> implemented) are sufficient.
Garbage collectors need roots. If I understand the situation correctly,
a StablePtr is itself a root, until explicitly freed. If you are handing out
the same object via the same StablePtr to several
different Foogle things, it seems to me you might attach a reference counter
to the StablePtr, so that when Foogle says "I am no longer interested in this
(Haskell) StablePtr", you decrement the reference counter by 1, and deallocate
if it reaches zero. Alternatively of course you could create a fresh StablePtr
every time something is passed to Foogle.
I think reference counters are sometimes used in things like CORBA, where
a similar problem arises. Of course they cannot cope with interlanguage cycles.
More information about the FFI