Temporarily take a resource from a Pool, perform an action with
it, and return it to the pool afterwards.

If the pool has an idle resource available, it is used
immediately.

Otherwise, if the maximum number of resources has not yet been
reached, a new resource is created and used.

If the maximum number of resources has been reached, this
function blocks until a resource becomes available.

If the action throws an exception of any type, the resource is
destroyed, and not returned to the pool.

It probably goes without saying that you should never manually
destroy a pooled resource, as doing so will almost certainly cause
a subsequent user (who expects the resource to be valid) to throw
an exception.