
This is exactly the guarantee you _don't_ have. The only guarantee you have is that it _won't_ be run if the Ptr _is_ being referenced.
From the GHC library documentation:
newForeignPtr :: FinalizerPtr a -> Ptr a -> IO (ForeignPtr a) [...] The only guarantee is that the finaliser runs before the program terminates.
So it seems, finalization *is* guaranteed, just not promptness of finalization.
http://www.haskell.org//pipermail/haskell-cafe/2004-October/007239.html http://www.haskell.org//pipermail/glasgow-haskell-users/2004-November/007450... See especially the second, where Simon M. says that Finalizers in GHC _usually_ run at program exit, but not _always_, and that this behavior may change in the future. I don't think that reality matches the documentation here, unfortunatly. I am unsure under what conditions finalizers won't be run -- but that such situations exist makes me very leary of using them.
My concern is that this approach is a little too non-deterministic. Because playing sound involves HW resources, [...]
If I understand correctly, the OP is dealing with library resources (mainly memory) while the library is managing the hardware ressources.
If the library automaticly releases hardware resources when they are no longer needed, then using finalizers to clean up isn't so bad. However, if the library waits for some kind of free call before freeing HW resources, then it is a bigger problem. It is unclear to me which is the case.