Search code examples
haskellgarbage-collectiondisposeghcfinalizer

How to dispose/release/"finalize" unmanaged resources when a shared value gets out of scope


I have a type that encapsulates a key to an external resource. Once the key is lost (all values that share it get out of scope), the resource should be released (implicitly) on the next garbage-collection, like memory does for regular values.

So I'm looking for something similar to OOP disposing, or ForeignPtr, only that I represent references to something other than objects from foreign languages (although if ForeignPtr can properly and elegantly work for this too, knowing how would also answer this question).

Is it possible? if so, how?


Solution

  • You can use System.Mem.Weak.addFinalizer for this.

    Unfortunately the semantics for weak references can be a little difficult to understand at first. The warning note is particularly important.

    If you can attach an IORef, MVar, or TVar to your key, and make a weak reference/finalizer associated with that, it's likely to be much more reliable.

    In the special case that your key is a pointer to non-managed memory (e.g. some C data structure), you should instead create a ForeignPtr and attach a finalizer to it. The semantics for these finalizers are a little different; rather than an arbitrary IO action the finalizer must be a function pointer to an external function.