Allocate and clean up a resource safely.
For more information on motivation and usage of this function, see
base's
bracket. This function has two differences from
the one in
base. The first, and more obvious, is that it
works on any
MonadUnliftIO instance, not just
IO.
The more subtle difference is that this function will use
uninterruptible masking for its cleanup handler. This is a subtle
distinction, but at a high level, means that resource cleanup has more
guarantees to complete. This comes at the cost that an incorrectly
written cleanup function cannot be interrupted.
For more information, please see
https://github.com/fpco/safe-exceptions/issues/3.