A foreign object is some data that lives outside the Haskell heap, for
example some malloc
ed data in C land. It's useful to be able to
know when the Haskell program no longer needs the malloc
ed data,
so it can be free
d. We can use weak pointers and finalizers for
this, but we have to be careful: the foreign data is usually
referenced by an address, ie. an Addr
(see Section
Addr), and we must retain the invariant that
if the Haskell program still needs the foreign object, then it
retains the Addr
object in the heap. This invariant isn't
guaranteed to hold if we use Addr
, because an Addr
consists
of a box around a raw address Addr#
. If the Haskell program can
manipulate the Addr#
object independently of the heap-resident
Addr
, then the foreign object could be inadvertently finalized
early, because a weak pointer to the Addr
would find no more
references to its key and trigger the finalizer despite the fact that
the program still holds the Addr#
and intends to use it.
To avoid this somewhat subtle race condition, we use another type of
foreign address, called ForeignObj
(see Section
Foreign). Historical note: ForeignObj
is identical to the old ForeignObj
except that it no longer
supports finalization - that's provided by the weak
pointer/finalization mechanism above.
A ForeignObj
is basically an address, but the ForeignObj
itself is a heap-resident object and can therefore be watched by weak
pointers. A ForeignObj
can be passed to C functions (in which
case the C function gets a straightforward pointer), but it cannot be
decomposed into an Addr#
.