This function ensures that the foreign object in
question is alive at the given place in the sequence of IO
actions. However, this comes with a significant caveat: the contract above
does not hold if GHC can demonstrate that the code preceding
touchForeignPtr diverges (e.g. by looping infinitely or throwing an
exception). For this reason, you are strongly advised to use instead
withForeignPtr where possible.
Also, note that this function should not be used to express dependencies
between finalizers on ForeignPtrs. For example, if the finalizer for a
ForeignPtr F1 calls touchForeignPtr on a second ForeignPtr F2,
then the only guarantee is that the finalizer for F2 is never started
before the finalizer for F1. They might be started together if for
example both F1 and F2 are otherwise unreachable, and in that case the
scheduler might end up running the finalizer for F2 first.
In general, it is not recommended to use finalizers on separate
objects with ordering constraints between them. To express the
ordering robustly requires explicit synchronisation using MVars
between the finalizers, but even then the runtime sometimes runs
multiple finalizers sequentially in a single thread (for
performance reasons), so synchronisation between finalizers could
result in artificial deadlock. Another alternative is to use
explicit reference counting.