Next Previous Contents

16.6 Finalization for foreign objects

A foreign object is some data that lives outside the Haskell heap, for example some malloced data in C land. It's useful to be able to know when the Haskell program no longer needs the malloced data, so it can be freed. 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#.


Next Previous Contents