    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE UndecidableInstances #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE ConstraintKinds #-}
    -- | Allocate resources which are guaranteed to be released.
    --
    -- For more information, see <https://github.com/snoyberg/conduit/tree/master/resourcet#readme>.
    --
    -- One point to note: all register cleanup actions live in the @IO@ monad, not
    -- the main monad. This allows both more efficient code, and for monads to be
    -- transformed.
    module Control.Monad.Trans.Resource
        ( -- * Data types
          ResourceT
        , ResIO
        , ReleaseKey
          -- * Unwrap
        , runResourceT
          -- ** Check cleanup exceptions
        , runResourceTChecked
        , ResourceCleanupException (..)
          -- * Special actions
        , resourceForkWith
        , resourceForkIO
          -- * Monad transformation
        , transResourceT
        , joinResourceT
          -- * Registering/releasing
        , allocate
        , allocate_
        , register
        , release
        , unprotect
        , resourceMask
          -- * Type class/associated types
        , MonadResource (..)
        , MonadResourceBase
          -- ** Low-level
        , InvalidAccess (..)
          -- * Re-exports
        , MonadUnliftIO
          -- * Internal state
          -- $internalState
        , InternalState
        , getInternalState
        , runInternalState
        , withInternalState
        , createInternalState
        , closeInternalState
          -- * Reexport
        , MonadThrow (..)
        ) where

    import qualified Data.IntMap as IntMap
    import qualified Data.IORef as I
    import Control.Monad.IO.Unlift (MonadIO (..), MonadUnliftIO, withRunInIO)
    import qualified Control.Exception as E

    import Control.Monad.Trans.Resource.Internal

    import Control.Concurrent (ThreadId, forkIO)

    import Control.Monad.Catch (MonadThrow, throwM)
    import Data.Acquire.Internal (ReleaseType (..))

    -- | Register some action that will be called precisely once, either when
    -- 'runResourceT' is called, or when the 'ReleaseKey' is passed to 'release'.
    --
    -- Since 0.3.0
    register :: MonadResource m => IO () -> m ReleaseKey
    register :: forall (m :: * -> *). MonadResource m => IO () -> m ReleaseKey
    register = ResourceT IO ReleaseKey -> m ReleaseKey
    forall a. ResourceT IO a -> m a
    forall (m :: * -> *) a. MonadResource m => ResourceT IO a -> m a
    liftResourceT (ResourceT IO ReleaseKey -> m ReleaseKey)
    -> (IO () -> ResourceT IO ReleaseKey) -> IO () -> m ReleaseKey
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IO () -> ResourceT IO ReleaseKey
    registerRIO

    -- | Call a release action early, and deregister it from the list of cleanup
    -- actions to be performed.
    --
    -- Since 0.3.0
    release :: MonadIO m => ReleaseKey -> m ()
    release :: forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
    release (ReleaseKey IORef ReleaseMap
    istate Int
    rk) = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ IORef ReleaseMap -> Int -> (Maybe (IO ()) -> IO ()) -> IO ()
    forall a.
    IORef ReleaseMap -> Int -> (Maybe (IO ()) -> IO a) -> IO a
    release' IORef ReleaseMap
    istate Int
    rk
        (IO () -> (IO () -> IO ()) -> Maybe (IO ()) -> IO ()
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (() -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()) IO () -> IO ()
    forall a. a -> a
    id)

    -- | Unprotect resource from cleanup actions; this allows you to send
    -- resource into another resourcet process and reregister it there.
    -- It returns a release action that should be run in order to clean
    -- resource or Nothing in case if resource is already freed.
    --
    -- Since 0.4.5
    unprotect :: MonadIO m => ReleaseKey -> m (Maybe (IO ()))
    unprotect :: forall (m :: * -> *). MonadIO m => ReleaseKey -> m (Maybe (IO ()))
    unprotect (ReleaseKey IORef ReleaseMap
    istate Int
    rk) = IO (Maybe (IO ())) -> m (Maybe (IO ()))
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Maybe (IO ())) -> m (Maybe (IO ())))
    -> IO (Maybe (IO ())) -> m (Maybe (IO ()))
    forall a b. (a -> b) -> a -> b
    $ IORef ReleaseMap
    -> Int
    -> (Maybe (IO ()) -> IO (Maybe (IO ())))
    -> IO (Maybe (IO ()))
    forall a.
    IORef ReleaseMap -> Int -> (Maybe (IO ()) -> IO a) -> IO a
    release' IORef ReleaseMap
    istate Int
    rk Maybe (IO ()) -> IO (Maybe (IO ()))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return

    -- | Perform some allocation, and automatically register a cleanup action.
    --
    -- This is almost identical to calling the allocation and then
    -- @register@ing the release action, but this properly handles masking of
    -- asynchronous exceptions.
    --
    -- Since 0.3.0
    allocate :: MonadResource m
             => IO a -- ^ allocate
             -> (a -> IO ()) -- ^ free resource
             -> m (ReleaseKey, a)
    allocate :: forall (m :: * -> *) a.
    MonadResource m =>
    IO a -> (a -> IO ()) -> m (ReleaseKey, a)
    allocate IO a
    a = ResourceT IO (ReleaseKey, a) -> m (ReleaseKey, a)
    forall a. ResourceT IO a -> m a
    forall (m :: * -> *) a. MonadResource m => ResourceT IO a -> m a
    liftResourceT (ResourceT IO (ReleaseKey, a) -> m (ReleaseKey, a))
    -> ((a -> IO ()) -> ResourceT IO (ReleaseKey, a))
    -> (a -> IO ())
    -> m (ReleaseKey, a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IO a -> (a -> IO ()) -> ResourceT IO (ReleaseKey, a)
    forall a. IO a -> (a -> IO ()) -> ResourceT IO (ReleaseKey, a)
    allocateRIO IO a
    a

    -- | Perform some allocation where the return value is not required, and
    -- automatically register a cleanup action.
    --
    -- @allocate_@ is to @allocate@ as @bracket_@ is to @bracket@
    --
    -- This is almost identical to calling the allocation and then
    -- @register@ing the release action, but this properly handles masking of
    -- asynchronous exceptions.
    --
    -- @since 1.2.4
    allocate_ :: MonadResource m
              => IO a -- ^ allocate
              -> IO () -- ^ free resource
              -> m ReleaseKey
    allocate_ :: forall (m :: * -> *) a.
    MonadResource m =>
    IO a -> IO () -> m ReleaseKey
    allocate_ IO a
    a = ((ReleaseKey, a) -> ReleaseKey)
    -> m (ReleaseKey, a) -> m ReleaseKey
    forall a b. (a -> b) -> m a -> m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (ReleaseKey, a) -> ReleaseKey
    forall a b. (a, b) -> a
    fst (m (ReleaseKey, a) -> m ReleaseKey)
    -> (IO () -> m (ReleaseKey, a)) -> IO () -> m ReleaseKey
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IO a -> (a -> IO ()) -> m (ReleaseKey, a)
    forall (m :: * -> *) a.
    MonadResource m =>
    IO a -> (a -> IO ()) -> m (ReleaseKey, a)
    allocate IO a
    a ((a -> IO ()) -> m (ReleaseKey, a))
    -> (IO () -> a -> IO ()) -> IO () -> m (ReleaseKey, a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IO () -> a -> IO ()
    forall a b. a -> b -> a
    const

    -- | Perform asynchronous exception masking.
    --
    -- This is more general then @Control.Exception.mask@, yet more efficient
    -- than @Control.Exception.Lifted.mask@.
    --
    -- Since 0.3.0
    resourceMask :: MonadResource m => ((forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b) -> m b
    resourceMask :: forall (m :: * -> *) b.
    MonadResource m =>
    ((forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b)
    -> m b
    resourceMask (forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b
    r = ResourceT IO b -> m b
    forall a. ResourceT IO a -> m a
    forall (m :: * -> *) a. MonadResource m => ResourceT IO a -> m a
    liftResourceT (((forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b)
    -> ResourceT IO b
    forall b.
    ((forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b)
    -> ResourceT IO b
    resourceMaskRIO (forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b
    r)

    allocateRIO :: IO a -> (a -> IO ()) -> ResourceT IO (ReleaseKey, a)
    allocateRIO :: forall a. IO a -> (a -> IO ()) -> ResourceT IO (ReleaseKey, a)
    allocateRIO IO a
    acquire a -> IO ()
    rel = (IORef ReleaseMap -> IO (ReleaseKey, a))
    -> ResourceT IO (ReleaseKey, a)
    forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    ResourceT ((IORef ReleaseMap -> IO (ReleaseKey, a))
     -> ResourceT IO (ReleaseKey, a))
    -> (IORef ReleaseMap -> IO (ReleaseKey, a))
    -> ResourceT IO (ReleaseKey, a)
    forall a b. (a -> b) -> a -> b
    $ \IORef ReleaseMap
    istate -> IO (ReleaseKey, a) -> IO (ReleaseKey, a)
    forall a. IO a -> IO a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (ReleaseKey, a) -> IO (ReleaseKey, a))
    -> IO (ReleaseKey, a) -> IO (ReleaseKey, a)
    forall a b. (a -> b) -> a -> b
    $ IO (ReleaseKey, a) -> IO (ReleaseKey, a)
    forall a. IO a -> IO a
    E.mask_ (IO (ReleaseKey, a) -> IO (ReleaseKey, a))
    -> IO (ReleaseKey, a) -> IO (ReleaseKey, a)
    forall a b. (a -> b) -> a -> b
    $ do
        a <- IO a
    acquire
        key <- register' istate $ rel a
        return (key, a)

    registerRIO :: IO () -> ResourceT IO ReleaseKey
    registerRIO :: IO () -> ResourceT IO ReleaseKey
    registerRIO IO ()
    rel = (IORef ReleaseMap -> IO ReleaseKey) -> ResourceT IO ReleaseKey
    forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    ResourceT ((IORef ReleaseMap -> IO ReleaseKey) -> ResourceT IO ReleaseKey)
    -> (IORef ReleaseMap -> IO ReleaseKey) -> ResourceT IO ReleaseKey
    forall a b. (a -> b) -> a -> b
    $ \IORef ReleaseMap
    istate -> IO ReleaseKey -> IO ReleaseKey
    forall a. IO a -> IO a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO ReleaseKey -> IO ReleaseKey) -> IO ReleaseKey -> IO ReleaseKey
    forall a b. (a -> b) -> a -> b
    $ IORef ReleaseMap -> IO () -> IO ReleaseKey
    register' IORef ReleaseMap
    istate IO ()
    rel

    resourceMaskRIO :: ((forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b) -> ResourceT IO b
    resourceMaskRIO :: forall b.
    ((forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b)
    -> ResourceT IO b
    resourceMaskRIO (forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b
    f = (IORef ReleaseMap -> IO b) -> ResourceT IO b
    forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    ResourceT ((IORef ReleaseMap -> IO b) -> ResourceT IO b)
    -> (IORef ReleaseMap -> IO b) -> ResourceT IO b
    forall a b. (a -> b) -> a -> b
    $ \IORef ReleaseMap
    istate -> IO b -> IO b
    forall a. IO a -> IO a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO b -> IO b) -> IO b -> IO b
    forall a b. (a -> b) -> a -> b
    $ ((forall a. IO a -> IO a) -> IO b) -> IO b
    forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
    E.mask (((forall a. IO a -> IO a) -> IO b) -> IO b)
    -> ((forall a. IO a -> IO a) -> IO b) -> IO b
    forall a b. (a -> b) -> a -> b
    $ \forall a. IO a -> IO a
    restore ->
        let ResourceT IORef ReleaseMap -> IO b
    f' = (forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b
    f ((forall a. IO a -> IO a)
    -> forall a. ResourceT IO a -> ResourceT IO a
    go IO a -> IO a
    forall a. IO a -> IO a
    restore)
         in IORef ReleaseMap -> IO b
    f' IORef ReleaseMap
    istate
      where
        go :: (forall a. IO a -> IO a) -> (forall a. ResourceT IO a -> ResourceT IO a)
        go :: (forall a. IO a -> IO a)
    -> forall a. ResourceT IO a -> ResourceT IO a
    go forall a. IO a -> IO a
    r (ResourceT IORef ReleaseMap -> IO a
    g) = (IORef ReleaseMap -> IO a) -> ResourceT IO a
    forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    ResourceT (\IORef ReleaseMap
    i -> IO a -> IO a
    forall a. IO a -> IO a
    r (IORef ReleaseMap -> IO a
    g IORef ReleaseMap
    i))

    release' :: I.IORef ReleaseMap
             -> Int
             -> (Maybe (IO ()) -> IO a)
             -> IO a
    release' :: forall a.
    IORef ReleaseMap -> Int -> (Maybe (IO ()) -> IO a) -> IO a
    release' IORef ReleaseMap
    istate Int
    key Maybe (IO ()) -> IO a
    act = IO a -> IO a
    forall a. IO a -> IO a
    E.mask_ (IO a -> IO a) -> IO a -> IO a
    forall a b. (a -> b) -> a -> b
    $ do
        maction <- IORef ReleaseMap
    -> (ReleaseMap -> (ReleaseMap, Maybe (IO ())))
    -> IO (Maybe (IO ()))
    forall a b. IORef a -> (a -> (a, b)) -> IO b
    I.atomicModifyIORef IORef ReleaseMap
    istate ReleaseMap -> (ReleaseMap, Maybe (IO ()))
    lookupAction
        act maction
      where
        lookupAction :: ReleaseMap -> (ReleaseMap, Maybe (IO ()))
    lookupAction rm :: ReleaseMap
    rm@(ReleaseMap Int
    next RefCount
    rf IntMap (ReleaseType -> IO ())
    m) =
            case Int
    -> IntMap (ReleaseType -> IO ()) -> Maybe (ReleaseType -> IO ())
    forall a. Int -> IntMap a -> Maybe a
    IntMap.lookup Int
    key IntMap (ReleaseType -> IO ())
    m of
                Maybe (ReleaseType -> IO ())
    Nothing -> (ReleaseMap
    rm, Maybe (IO ())
    forall a. Maybe a
    Nothing)
                Just ReleaseType -> IO ()
    action ->
                    ( Int -> RefCount -> IntMap (ReleaseType -> IO ()) -> ReleaseMap
    ReleaseMap Int
    next RefCount
    rf (IntMap (ReleaseType -> IO ()) -> ReleaseMap)
    -> IntMap (ReleaseType -> IO ()) -> ReleaseMap
    forall a b. (a -> b) -> a -> b
    $ Int
    -> IntMap (ReleaseType -> IO ()) -> IntMap (ReleaseType -> IO ())
    forall a. Int -> IntMap a -> IntMap a
    IntMap.delete Int
    key IntMap (ReleaseType -> IO ())
    m
                    , IO () -> Maybe (IO ())
    forall a. a -> Maybe a
    Just (ReleaseType -> IO ()
    action ReleaseType
    ReleaseEarly)
                    )
        -- We tried to call release, but since the state is already closed, we
        -- can assume that the release action was already called. Previously,
        -- this threw an exception, though given that @release@ can be called
        -- from outside the context of a @ResourceT@ starting with version
        -- 0.4.4, it's no longer a library misuse or a library bug.
        lookupAction ReleaseMap
    ReleaseMapClosed = (ReleaseMap
    ReleaseMapClosed, Maybe (IO ())
    forall a. Maybe a
    Nothing)

    -- | Unwrap a 'ResourceT' transformer, and call all registered release actions.
    --
    -- Note that there is some reference counting involved due to 'resourceForkIO'.
    -- If multiple threads are sharing the same collection of resources, only the
    -- last call to @runResourceT@ will deallocate the resources.
    --
    -- /NOTE/ Since version 1.2.0, this function will throw a
    -- 'ResourceCleanupException' if any of the cleanup functions throw an
    -- exception.
    --
    -- @since 0.3.0
    runResourceT :: MonadUnliftIO m => ResourceT m a -> m a
    runResourceT :: forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
    runResourceT (ResourceT IORef ReleaseMap -> m a
    r) = ((forall a. m a -> IO a) -> IO a) -> m a
    forall b. ((forall a. m a -> IO a) -> IO b) -> m b
    forall (m :: * -> *) b.
    MonadUnliftIO m =>
    ((forall a. m a -> IO a) -> IO b) -> m b
    withRunInIO (((forall a. m a -> IO a) -> IO a) -> m a)
    -> ((forall a. m a -> IO a) -> IO a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \forall a. m a -> IO a
    run -> do
        istate <- IO (IORef ReleaseMap)
    forall (m :: * -> *). MonadIO m => m (IORef ReleaseMap)
    createInternalState
        E.mask $ \forall a. IO a -> IO a
    restore -> do
            res <- IO a -> IO a
    forall a. IO a -> IO a
    restore (m a -> IO a
    forall a. m a -> IO a
    run (IORef ReleaseMap -> m a
    r IORef ReleaseMap
    istate)) IO a -> (SomeException -> IO a) -> IO a
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    `E.catch` \SomeException
    e -> do
                Maybe SomeException -> IORef ReleaseMap -> IO ()
    stateCleanupChecked (SomeException -> Maybe SomeException
    forall a. a -> Maybe a
    Just SomeException
    e) IORef ReleaseMap
    istate
                SomeException -> IO a
    forall e a. (HasCallStack, Exception e) => e -> IO a
    E.throwIO SomeException
    e
            stateCleanupChecked Nothing istate
            return res

    -- | Backwards compatible alias for 'runResourceT'.
    --
    -- @since 1.1.11
    runResourceTChecked :: MonadUnliftIO m => ResourceT m a -> m a
    runResourceTChecked :: forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
    runResourceTChecked = ResourceT m a -> m a
    forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
    runResourceT
    {-# INLINE runResourceTChecked #-}

    bracket_ :: MonadUnliftIO m
             => IO () -- ^ allocate
             -> IO () -- ^ normal cleanup
             -> (E.SomeException -> IO ()) -- ^ exceptional cleanup
             -> m a
             -> m a
    bracket_ :: forall (m :: * -> *) a.
    MonadUnliftIO m =>
    IO () -> IO () -> (SomeException -> IO ()) -> m a -> m a
    bracket_ IO ()
    alloc IO ()
    cleanupNormal SomeException -> IO ()
    cleanupExc m a
    inside =
        ((forall a. m a -> IO a) -> IO a) -> m a
    forall b. ((forall a. m a -> IO a) -> IO b) -> m b
    forall (m :: * -> *) b.
    MonadUnliftIO m =>
    ((forall a. m a -> IO a) -> IO b) -> m b
    withRunInIO (((forall a. m a -> IO a) -> IO a) -> m a)
    -> ((forall a. m a -> IO a) -> IO a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \forall a. m a -> IO a
    run -> ((forall a. IO a -> IO a) -> IO a) -> IO a
    forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
    E.mask (((forall a. IO a -> IO a) -> IO a) -> IO a)
    -> ((forall a. IO a -> IO a) -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ \forall a. IO a -> IO a
    restore -> do
            IO ()
    alloc
            res <- IO a -> IO a
    forall a. IO a -> IO a
    restore (m a -> IO a
    forall a. m a -> IO a
    run m a
    inside) IO a -> (SomeException -> IO a) -> IO a
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    `E.catch` (\SomeException
    e -> SomeException -> IO ()
    cleanupExc SomeException
    e IO () -> IO a -> IO a
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> SomeException -> IO a
    forall e a. (HasCallStack, Exception e) => e -> IO a
    E.throwIO SomeException
    e)
            cleanupNormal
            return res

    -- | This function mirrors @join@ at the transformer level: it will collapse
    -- two levels of @ResourceT@ into a single @ResourceT@.
    --
    -- Since 0.4.6
    joinResourceT :: ResourceT (ResourceT m) a
                  -> ResourceT m a
    joinResourceT :: forall (m :: * -> *) a. ResourceT (ResourceT m) a -> ResourceT m a
    joinResourceT (ResourceT IORef ReleaseMap -> ResourceT m a
    f) = (IORef ReleaseMap -> m a) -> ResourceT m a
    forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    ResourceT ((IORef ReleaseMap -> m a) -> ResourceT m a)
    -> (IORef ReleaseMap -> m a) -> ResourceT m a
    forall a b. (a -> b) -> a -> b
    $ \IORef ReleaseMap
    r -> ResourceT m a -> IORef ReleaseMap -> m a
    forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
    unResourceT (IORef ReleaseMap -> ResourceT m a
    f IORef ReleaseMap
    r) IORef ReleaseMap
    r

    -- | Introduce a reference-counting scheme to allow a resource context to be
    -- shared by multiple threads. Once the last thread exits, all remaining
    -- resources will be released.
    --
    -- The first parameter is a function which will be used to create the
    -- thread, such as @forkIO@ or @async@.
    --
    -- Note that abuse of this function will greatly delay the deallocation of
    -- registered resources. This function should be used with care. A general
    -- guideline:
    --
    -- If you are allocating a resource that should be shared by multiple threads,
    -- and will be held for a long time, you should allocate it at the beginning of
    -- a new @ResourceT@ block and then call @resourceForkWith@ from there.
    --
    -- @since 1.1.9
    resourceForkWith
      :: MonadUnliftIO m
      => (IO () -> IO a)
      -> ResourceT m ()
      -> ResourceT m a
    resourceForkWith :: forall (m :: * -> *) a.
    MonadUnliftIO m =>
    (IO () -> IO a) -> ResourceT m () -> ResourceT m a
    resourceForkWith IO () -> IO a
    g (ResourceT IORef ReleaseMap -> m ()
    f) =
      (IORef ReleaseMap -> m a) -> ResourceT m a
    forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    ResourceT ((IORef ReleaseMap -> m a) -> ResourceT m a)
    -> (IORef ReleaseMap -> m a) -> ResourceT m a
    forall a b. (a -> b) -> a -> b
    $ \IORef ReleaseMap
    r -> ((forall a. m a -> IO a) -> IO a) -> m a
    forall b. ((forall a. m a -> IO a) -> IO b) -> m b
    forall (m :: * -> *) b.
    MonadUnliftIO m =>
    ((forall a. m a -> IO a) -> IO b) -> m b
    withRunInIO (((forall a. m a -> IO a) -> IO a) -> m a)
    -> ((forall a. m a -> IO a) -> IO a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \forall a. m a -> IO a
    run -> ((forall a. IO a -> IO a) -> IO a) -> IO a
    forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
    E.mask (((forall a. IO a -> IO a) -> IO a) -> IO a)
    -> ((forall a. IO a -> IO a) -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ \forall a. IO a -> IO a
    restore ->
        -- We need to make sure the counter is incremented before this call
        -- returns. Otherwise, the parent thread may call runResourceT before
        -- the child thread increments, and all resources will be freed
        -- before the child gets called.
        IO () -> IO () -> (SomeException -> IO ()) -> IO a -> IO a
    forall (m :: * -> *) a.
    MonadUnliftIO m =>
    IO () -> IO () -> (SomeException -> IO ()) -> m a -> m a
    bracket_
            (IORef ReleaseMap -> IO ()
    stateAlloc IORef ReleaseMap
    r)
            (() -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())
            (IO () -> SomeException -> IO ()
    forall a b. a -> b -> a
    const (IO () -> SomeException -> IO ())
    -> IO () -> SomeException -> IO ()
    forall a b. (a -> b) -> a -> b
    $ () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())
            (IO () -> IO a
    g (IO () -> IO a) -> IO () -> IO a
    forall a b. (a -> b) -> a -> b
    $ IO () -> IO () -> (SomeException -> IO ()) -> IO () -> IO ()
    forall (m :: * -> *) a.
    MonadUnliftIO m =>
    IO () -> IO () -> (SomeException -> IO ()) -> m a -> m a
    bracket_
                (() -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())
                (ReleaseType -> IORef ReleaseMap -> IO ()
    stateCleanup ReleaseType
    ReleaseNormal IORef ReleaseMap
    r)
                (\SomeException
    e -> ReleaseType -> IORef ReleaseMap -> IO ()
    stateCleanup (SomeException -> ReleaseType
    ReleaseExceptionWith SomeException
    e) IORef ReleaseMap
    r)
                (IO () -> IO ()
    forall a. IO a -> IO a
    restore (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ m () -> IO ()
    forall a. m a -> IO a
    run (m () -> IO ()) -> m () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ IORef ReleaseMap -> m ()
    f IORef ReleaseMap
    r))

    -- | Launch a new reference counted resource context using @forkIO@.
    --
    -- This is defined as @resourceForkWith forkIO@.
    --
    -- Note: Using regular 'forkIO' inside of a 'ResourceT' is inherently unsafe,
    -- since the forked thread may try access the resources of the parent after they are cleaned up.
    -- When you use 'resourceForkIO' or 'resourceForkWith', 'ResourceT' is made aware of the new thread, and will only cleanup resources when all threads finish.
    -- Other concurrency mechanisms, like 'concurrently' or 'race', are safe to use.
    --
    -- If you encounter 'InvalidAccess' exceptions ("The mutable state is being accessed after cleanup"),
    -- use of 'forkIO' is a possible culprit.
    --
    -- @since 0.3.0
    resourceForkIO :: MonadUnliftIO m => ResourceT m () -> ResourceT m ThreadId
    resourceForkIO :: forall (m :: * -> *).
    MonadUnliftIO m =>
    ResourceT m () -> ResourceT m ThreadId
    resourceForkIO = (IO () -> IO ThreadId) -> ResourceT m () -> ResourceT m ThreadId
    forall (m :: * -> *) a.
    MonadUnliftIO m =>
    (IO () -> IO a) -> ResourceT m () -> ResourceT m a
    resourceForkWith IO () -> IO ThreadId
    forkIO

    -- | Just use 'MonadUnliftIO' directly now, legacy explanation continues:
    --
    -- A @Monad@ which can be used as a base for a @ResourceT@.
    --
    -- A @ResourceT@ has some restrictions on its base monad:
    --
    -- * @runResourceT@ requires an instance of @MonadUnliftIO@.
    -- * @MonadResource@ requires an instance of @MonadIO@
    --
    -- Note that earlier versions of @conduit@ had a typeclass @ResourceIO@. This
    -- fulfills much the same role.
    --
    -- Since 0.3.2
    type MonadResourceBase = MonadUnliftIO
    {-# DEPRECATED MonadResourceBase "Use MonadUnliftIO directly instead" #-}

    -- $internalState
    --
    -- A @ResourceT@ internally is a modified @ReaderT@ monad transformer holding
    -- onto a mutable reference to all of the release actions still remaining to be
    -- performed. If you are building up a custom application monad, it may be more
    -- efficient to embed this @ReaderT@ functionality directly in your own monad
    -- instead of wrapping around @ResourceT@ itself. This section provides you the
    -- means of doing so.

    -- | Create a new internal state. This state must be closed with
    -- @closeInternalState@. It is your responsibility to ensure exception safety.
    -- Caveat emptor!
    --
    -- Since 0.4.9
    createInternalState :: MonadIO m => m InternalState
    createInternalState :: forall (m :: * -> *). MonadIO m => m (IORef ReleaseMap)
    createInternalState = IO (IORef ReleaseMap) -> m (IORef ReleaseMap)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO
                        (IO (IORef ReleaseMap) -> m (IORef ReleaseMap))
    -> IO (IORef ReleaseMap) -> m (IORef ReleaseMap)
    forall a b. (a -> b) -> a -> b
    $ ReleaseMap -> IO (IORef ReleaseMap)
    forall a. a -> IO (IORef a)
    I.newIORef
                        (ReleaseMap -> IO (IORef ReleaseMap))
    -> ReleaseMap -> IO (IORef ReleaseMap)
    forall a b. (a -> b) -> a -> b
    $ Int -> RefCount -> IntMap (ReleaseType -> IO ()) -> ReleaseMap
    ReleaseMap Int
    forall a. Bounded a => a
    maxBound (RefCount
    forall a. Bounded a => a
    minBound RefCount -> RefCount -> RefCount
    forall a. Num a => a -> a -> a
    + RefCount
    1) IntMap (ReleaseType -> IO ())
    forall a. IntMap a
    IntMap.empty

    -- | Close an internal state created by @createInternalState@.
    --
    -- Since 0.4.9
    closeInternalState :: MonadIO m => InternalState -> m ()
    closeInternalState :: forall (m :: * -> *). MonadIO m => IORef ReleaseMap -> m ()
    closeInternalState = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ())
    -> (IORef ReleaseMap -> IO ()) -> IORef ReleaseMap -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ReleaseType -> IORef ReleaseMap -> IO ()
    stateCleanup ReleaseType
    ReleaseNormal

    -- | Get the internal state of the current @ResourceT@.
    --
    -- Since 0.4.6
    getInternalState :: Monad m => ResourceT m InternalState
    getInternalState :: forall (m :: * -> *). Monad m => ResourceT m (IORef ReleaseMap)
    getInternalState = (IORef ReleaseMap -> m (IORef ReleaseMap))
    -> ResourceT m (IORef ReleaseMap)
    forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    ResourceT IORef ReleaseMap -> m (IORef ReleaseMap)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return

    -- | The internal state held by a @ResourceT@ transformer.
    --
    -- Since 0.4.6
    type InternalState = I.IORef ReleaseMap

    -- | Unwrap a @ResourceT@ using the given @InternalState@.
    --
    -- Since 0.4.6
    runInternalState :: ResourceT m a -> InternalState -> m a
    runInternalState :: forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
    runInternalState = ResourceT m a -> IORef ReleaseMap -> m a
    forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
    unResourceT

    -- | Run an action in the underlying monad, providing it the @InternalState@.
    --
    -- Since 0.4.6
    withInternalState :: (InternalState -> m a) -> ResourceT m a
    withInternalState :: forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    withInternalState = (IORef ReleaseMap -> m a) -> ResourceT m a
    forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
    ResourceT