{-# OPTIONS_HADDOCK not-home #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE RankNTypes #-}
module Control.Monad.Trans.Resource.Internal(
InvalidAccess(..)
, MonadResource(..)
, ReleaseKey(..)
, ReleaseMap(..)
, ResIO
, ResourceT(..)
, stateAlloc
, stateCleanup
, transResourceT
, register'
, registerType
, ResourceCleanupException (..)
, stateCleanupChecked
) where
import Control.Exception (throw,Exception,SomeException)
import Control.Applicative (Applicative (..), Alternative(..))
import Control.Monad (MonadPlus(..))
import Control.Monad.Fail (MonadFail(..))
import Control.Monad.Fix (MonadFix(..))
import Control.Monad.IO.Unlift
import Control.Monad.Trans.Class (MonadTrans (..))
import Control.Monad.Trans.Cont ( ContT )
import Control.Monad.Cont.Class ( MonadCont (..) )
import Control.Monad.Error.Class ( MonadError (..) )
import Control.Monad.RWS.Class ( MonadRWS )
import Control.Monad.Reader.Class ( MonadReader (..) )
import Control.Monad.State.Class ( MonadState (..) )
import Control.Monad.Writer.Class ( MonadWriter (..) )
import Control.Monad.Trans.Identity ( IdentityT)
#if !MIN_VERSION_transformers(0,6,0)
import Control.Monad.Trans.List ( ListT )
#endif
import Control.Monad.Trans.Maybe ( MaybeT )
import Control.Monad.Trans.Except ( ExceptT )
import Control.Monad.Trans.Reader ( ReaderT )
import Control.Monad.Trans.State ( StateT )
import Control.Monad.Trans.Writer ( WriterT )
import Control.Monad.Trans.RWS ( RWST )
import qualified Control.Monad.Trans.RWS.Strict as Strict ( RWST )
import qualified Control.Monad.Trans.State.Strict as Strict ( StateT )
import qualified Control.Monad.Trans.Writer.Strict as Strict ( WriterT )
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Primitive (PrimMonad (..))
import qualified Control.Exception as E
import Control.Monad.Catch (MonadThrow (..), MonadCatch (..), MonadMask (..))
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import qualified Data.IORef as I
import Data.Typeable
import Data.Word(Word)
import Data.Acquire.Internal (ReleaseType (..))
class MonadIO m => MonadResource m where
liftResourceT :: ResourceT IO a -> m a
data ReleaseKey = ReleaseKey !(I.IORef ReleaseMap) !Int
deriving Typeable
type RefCount = Word
type NextKey = Int
data ReleaseMap =
ReleaseMap !NextKey !RefCount !(IntMap (ReleaseType -> IO ()))
| ReleaseMapClosed
type ResIO = ResourceT IO
instance MonadCont m => MonadCont (ResourceT m) where
callCC :: forall a b.
((a -> ResourceT m b) -> ResourceT m a) -> ResourceT m a
callCC (a -> ResourceT m b) -> ResourceT m a
f = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
i -> forall (m :: * -> *) a b. MonadCont m => ((a -> m b) -> m a) -> m a
callCC forall a b. (a -> b) -> a -> b
$ \a -> m b
c -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ((a -> ResourceT m b) -> ResourceT m a
f (forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m b
c)) IORef ReleaseMap
i
instance MonadError e m => MonadError e (ResourceT m) where
throwError :: forall a. e -> ResourceT m a
throwError = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
catchError :: forall a. ResourceT m a -> (e -> ResourceT m a) -> ResourceT m a
catchError ResourceT m a
r e -> ResourceT m a
h = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
i -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ResourceT m a
r IORef ReleaseMap
i forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
`catchError` \e
e -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT (e -> ResourceT m a
h e
e) IORef ReleaseMap
i
instance MonadRWS r w s m => MonadRWS r w s (ResourceT m)
instance MonadReader r m => MonadReader r (ResourceT m) where
ask :: ResourceT m r
ask = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall r (m :: * -> *). MonadReader r m => m r
ask
local :: forall a. (r -> r) -> ResourceT m a -> ResourceT m a
local = forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
mapResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local
mapResourceT :: (m a -> n b) -> ResourceT m a -> ResourceT n b
mapResourceT :: forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
mapResourceT m a -> n b
f = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. (m a -> n b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT
instance MonadState s m => MonadState s (ResourceT m) where
get :: ResourceT m s
get = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall s (m :: * -> *). MonadState s m => m s
get
put :: s -> ResourceT m ()
put = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s (m :: * -> *). MonadState s m => s -> m ()
put
instance MonadWriter w m => MonadWriter w (ResourceT m) where
tell :: w -> ResourceT m ()
tell = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell
listen :: forall a. ResourceT m a -> ResourceT m (a, w)
listen = forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
mapResourceT forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen
pass :: forall a. ResourceT m (a, w -> w) -> ResourceT m a
pass = forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
mapResourceT forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
pass
instance MonadThrow m => MonadThrow (ResourceT m) where
throwM :: forall e a. Exception e => e -> ResourceT m a
throwM = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM
instance MonadCatch m => MonadCatch (ResourceT m) where
catch :: forall e a.
Exception e =>
ResourceT m a -> (e -> ResourceT m a) -> ResourceT m a
catch (ResourceT IORef ReleaseMap -> m a
m) e -> ResourceT m a
c =
forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r -> IORef ReleaseMap -> m a
m IORef ReleaseMap
r forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` \e
e -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT (e -> ResourceT m a
c e
e) IORef ReleaseMap
r
instance MonadMask m => MonadMask (ResourceT m) where
mask :: forall b.
((forall a. ResourceT m a -> ResourceT m a) -> ResourceT m b)
-> ResourceT m b
mask (forall a. ResourceT m a -> ResourceT m a) -> ResourceT m b
a = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
e -> forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
u -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ((forall a. ResourceT m a -> ResourceT m a) -> ResourceT m b
a forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
q forall a. m a -> m a
u) IORef ReleaseMap
e
where q :: (m a -> m a) -> ResourceT m a -> ResourceT m a
q m a -> m a
u (ResourceT IORef ReleaseMap -> m a
b) = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT (m a -> m a
u forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef ReleaseMap -> m a
b)
uninterruptibleMask :: forall b.
((forall a. ResourceT m a -> ResourceT m a) -> ResourceT m b)
-> ResourceT m b
uninterruptibleMask (forall a. ResourceT m a -> ResourceT m a) -> ResourceT m b
a =
forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
e -> forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
uninterruptibleMask forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
u -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ((forall a. ResourceT m a -> ResourceT m a) -> ResourceT m b
a forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
q forall a. m a -> m a
u) IORef ReleaseMap
e
where q :: (m a -> m a) -> ResourceT m a -> ResourceT m a
q m a -> m a
u (ResourceT IORef ReleaseMap -> m a
b) = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT (m a -> m a
u forall b c a. (b -> c) -> (a -> b) -> a -> c
. IORef ReleaseMap -> m a
b)
#if MIN_VERSION_exceptions(0, 10, 0)
generalBracket :: forall a b c.
ResourceT m a
-> (a -> ExitCase b -> ResourceT m c)
-> (a -> ResourceT m b)
-> ResourceT m (b, c)
generalBracket ResourceT m a
acquire a -> ExitCase b -> ResourceT m c
release a -> ResourceT m b
use =
forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r ->
forall (m :: * -> *) a b c.
MonadMask m =>
m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
generalBracket
( forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ResourceT m a
acquire IORef ReleaseMap
r )
( \a
resource ExitCase b
exitCase ->
forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ( a -> ExitCase b -> ResourceT m c
release a
resource ExitCase b
exitCase ) IORef ReleaseMap
r
)
( \a
resource -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ( a -> ResourceT m b
use a
resource ) IORef ReleaseMap
r )
#elif MIN_VERSION_exceptions(0, 9, 0)
#error exceptions 0.9.0 is not supported
#endif
instance MonadIO m => MonadResource (ResourceT m) where
liftResourceT :: forall a. ResourceT IO a -> ResourceT m a
liftResourceT = forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
transResourceT forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
instance PrimMonad m => PrimMonad (ResourceT m) where
type PrimState (ResourceT m) = PrimState m
primitive :: forall a.
(State# (PrimState (ResourceT m))
-> (# State# (PrimState (ResourceT m)), a #))
-> ResourceT m a
primitive = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive
transResourceT :: (m a -> n b)
-> ResourceT m a
-> ResourceT n b
transResourceT :: forall (m :: * -> *) a (n :: * -> *) b.
(m a -> n b) -> ResourceT m a -> ResourceT n b
transResourceT m a -> n b
f (ResourceT IORef ReleaseMap -> m a
mx) = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT (\IORef ReleaseMap
r -> m a -> n b
f (IORef ReleaseMap -> m a
mx IORef ReleaseMap
r))
newtype ResourceT m a = ResourceT { forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT :: I.IORef ReleaseMap -> m a }
#if __GLASGOW_HASKELL__ >= 707
deriving Typeable
#else
instance Typeable1 m => Typeable1 (ResourceT m) where
typeOf1 = goType undefined
where
goType :: Typeable1 m => m a -> ResourceT m a -> TypeRep
goType m _ =
mkTyConApp
#if __GLASGOW_HASKELL__ >= 704
(mkTyCon3 "resourcet" "Control.Monad.Trans.Resource" "ResourceT")
#else
(mkTyCon "Control.Monad.Trans.Resource.ResourceT")
#endif
[ typeOf1 m
]
#endif
data InvalidAccess = InvalidAccess { InvalidAccess -> String
functionName :: String }
deriving Typeable
instance Show InvalidAccess where
show :: InvalidAccess -> String
show (InvalidAccess String
f) = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ String
"Control.Monad.Trans.Resource."
, String
f
, String
": The mutable state is being accessed after cleanup. Please contact the maintainers."
]
instance Exception InvalidAccess
instance Functor m => Functor (ResourceT m) where
fmap :: forall a b. (a -> b) -> ResourceT m a -> ResourceT m b
fmap a -> b
f (ResourceT IORef ReleaseMap -> m a
m) = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (IORef ReleaseMap -> m a
m IORef ReleaseMap
r)
instance Applicative m => Applicative (ResourceT m) where
pure :: forall a. a -> ResourceT m a
pure = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure
ResourceT IORef ReleaseMap -> m (a -> b)
mf <*> :: forall a b. ResourceT m (a -> b) -> ResourceT m a -> ResourceT m b
<*> ResourceT IORef ReleaseMap -> m a
ma = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r ->
IORef ReleaseMap -> m (a -> b)
mf IORef ReleaseMap
r forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IORef ReleaseMap -> m a
ma IORef ReleaseMap
r
ResourceT IORef ReleaseMap -> m a
mf *> :: forall a b. ResourceT m a -> ResourceT m b -> ResourceT m b
*> ResourceT IORef ReleaseMap -> m b
ma = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r ->
IORef ReleaseMap -> m a
mf IORef ReleaseMap
r forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> IORef ReleaseMap -> m b
ma IORef ReleaseMap
r
ResourceT IORef ReleaseMap -> m a
mf <* :: forall a b. ResourceT m a -> ResourceT m b -> ResourceT m a
<* ResourceT IORef ReleaseMap -> m b
ma = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r ->
IORef ReleaseMap -> m a
mf IORef ReleaseMap
r forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* IORef ReleaseMap -> m b
ma IORef ReleaseMap
r
instance Alternative m => Alternative (ResourceT m) where
empty :: forall a. ResourceT m a
empty = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
_ -> forall (f :: * -> *) a. Alternative f => f a
empty
(ResourceT IORef ReleaseMap -> m a
mf) <|> :: forall a. ResourceT m a -> ResourceT m a -> ResourceT m a
<|> (ResourceT IORef ReleaseMap -> m a
ma) = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r -> IORef ReleaseMap -> m a
mf IORef ReleaseMap
r forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> IORef ReleaseMap -> m a
ma IORef ReleaseMap
r
instance MonadPlus m => MonadPlus (ResourceT m) where
mzero :: forall a. ResourceT m a
mzero = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
_ -> forall (m :: * -> *) a. MonadPlus m => m a
mzero
(ResourceT IORef ReleaseMap -> m a
mf) mplus :: forall a. ResourceT m a -> ResourceT m a -> ResourceT m a
`mplus` (ResourceT IORef ReleaseMap -> m a
ma) = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r -> IORef ReleaseMap -> m a
mf IORef ReleaseMap
r forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` IORef ReleaseMap -> m a
ma IORef ReleaseMap
r
instance Monad m => Monad (ResourceT m) where
return :: forall a. a -> ResourceT m a
return = forall (f :: * -> *) a. Applicative f => a -> f a
pure
ResourceT IORef ReleaseMap -> m a
ma >>= :: forall a b. ResourceT m a -> (a -> ResourceT m b) -> ResourceT m b
>>= a -> ResourceT m b
f = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r -> do
a
a <- IORef ReleaseMap -> m a
ma IORef ReleaseMap
r
let ResourceT IORef ReleaseMap -> m b
f' = a -> ResourceT m b
f a
a
IORef ReleaseMap -> m b
f' IORef ReleaseMap
r
instance MonadFail m => MonadFail (ResourceT m) where
fail :: forall a. String -> ResourceT m a
fail = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadFail m => String -> m a
Control.Monad.Fail.fail
instance MonadFix m => MonadFix (ResourceT m) where
mfix :: forall a. (a -> ResourceT m a) -> ResourceT m a
mfix a -> ResourceT m a
f = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r -> forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
mfix forall a b. (a -> b) -> a -> b
$ \a
a -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT (a -> ResourceT m a
f a
a) IORef ReleaseMap
r
instance MonadTrans ResourceT where
lift :: forall (m :: * -> *) a. Monad m => m a -> ResourceT m a
lift = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> b -> a
const
instance MonadIO m => MonadIO (ResourceT m) where
liftIO :: forall a. IO a -> ResourceT m a
liftIO = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
instance MonadUnliftIO m => MonadUnliftIO (ResourceT m) where
{-# INLINE withRunInIO #-}
withRunInIO :: forall b.
((forall a. ResourceT m a -> IO a) -> IO b) -> ResourceT m b
withRunInIO (forall a. ResourceT m a -> IO a) -> IO b
inner =
forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
r ->
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run ->
(forall a. ResourceT m a -> IO a) -> IO b
inner (forall a. m a -> IO a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT IORef ReleaseMap
r)
#define GO(T) instance (MonadResource m) => MonadResource (T m) where liftResourceT = lift . liftResourceT
#define GOX(X, T) instance (X, MonadResource m) => MonadResource (T m) where liftResourceT = lift . liftResourceT
GO(IdentityT)
#if !MIN_VERSION_transformers(0,6,0)
GO(ListT)
#endif
GO(MaybeT)
GO(ExceptT e)
GO(ReaderT r)
GO(ContT r)
GO(StateT s)
GOX(Monoid w, WriterT w)
GOX(Monoid w, RWST r w s)
GOX(Monoid w, Strict.RWST r w s)
GO(Strict.StateT s)
GOX(Monoid w, Strict.WriterT w)
#undef GO
#undef GOX
stateAlloc :: I.IORef ReleaseMap -> IO ()
stateAlloc :: IORef ReleaseMap -> IO ()
stateAlloc IORef ReleaseMap
istate = do
forall a b. IORef a -> (a -> (a, b)) -> IO b
I.atomicModifyIORef IORef ReleaseMap
istate forall a b. (a -> b) -> a -> b
$ \ReleaseMap
rm ->
case ReleaseMap
rm of
ReleaseMap NextKey
nk RefCount
rf IntMap (ReleaseType -> IO ())
m ->
(NextKey -> RefCount -> IntMap (ReleaseType -> IO ()) -> ReleaseMap
ReleaseMap NextKey
nk (RefCount
rf forall a. Num a => a -> a -> a
+ RefCount
1) IntMap (ReleaseType -> IO ())
m, ())
ReleaseMap
ReleaseMapClosed -> forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> InvalidAccess
InvalidAccess String
"stateAlloc"
stateCleanup :: ReleaseType -> I.IORef ReleaseMap -> IO ()
stateCleanup :: ReleaseType -> IORef ReleaseMap -> IO ()
stateCleanup ReleaseType
rtype IORef ReleaseMap
istate = forall a. IO a -> IO a
E.mask_ forall a b. (a -> b) -> a -> b
$ do
Maybe (IntMap (ReleaseType -> IO ()))
mm <- forall a b. IORef a -> (a -> (a, b)) -> IO b
I.atomicModifyIORef IORef ReleaseMap
istate forall a b. (a -> b) -> a -> b
$ \ReleaseMap
rm ->
case ReleaseMap
rm of
ReleaseMap NextKey
nk RefCount
rf IntMap (ReleaseType -> IO ())
m ->
let rf' :: RefCount
rf' = RefCount
rf forall a. Num a => a -> a -> a
- RefCount
1
in if RefCount
rf' forall a. Eq a => a -> a -> Bool
== forall a. Bounded a => a
minBound
then (ReleaseMap
ReleaseMapClosed, forall a. a -> Maybe a
Just IntMap (ReleaseType -> IO ())
m)
else (NextKey -> RefCount -> IntMap (ReleaseType -> IO ()) -> ReleaseMap
ReleaseMap NextKey
nk RefCount
rf' IntMap (ReleaseType -> IO ())
m, forall a. Maybe a
Nothing)
ReleaseMap
ReleaseMapClosed -> forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> InvalidAccess
InvalidAccess String
"stateCleanup"
case Maybe (IntMap (ReleaseType -> IO ()))
mm of
Just IntMap (ReleaseType -> IO ())
m ->
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\ReleaseType -> IO ()
x -> forall a. IO a -> IO (Either SomeException a)
try (ReleaseType -> IO ()
x ReleaseType
rtype) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ()) forall a b. (a -> b) -> a -> b
$ forall a. IntMap a -> [a]
IntMap.elems IntMap (ReleaseType -> IO ())
m
Maybe (IntMap (ReleaseType -> IO ()))
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
try :: IO a -> IO (Either SomeException a)
try :: forall a. IO a -> IO (Either SomeException a)
try = forall e a. Exception e => IO a -> IO (Either e a)
E.try
register' :: I.IORef ReleaseMap
-> IO ()
-> IO ReleaseKey
register' :: IORef ReleaseMap -> IO () -> IO ReleaseKey
register' IORef ReleaseMap
istate IO ()
rel = forall a b. IORef a -> (a -> (a, b)) -> IO b
I.atomicModifyIORef IORef ReleaseMap
istate forall a b. (a -> b) -> a -> b
$ \ReleaseMap
rm ->
case ReleaseMap
rm of
ReleaseMap NextKey
key RefCount
rf IntMap (ReleaseType -> IO ())
m ->
( NextKey -> RefCount -> IntMap (ReleaseType -> IO ()) -> ReleaseMap
ReleaseMap (NextKey
key forall a. Num a => a -> a -> a
- NextKey
1) RefCount
rf (forall a. NextKey -> a -> IntMap a -> IntMap a
IntMap.insert NextKey
key (forall a b. a -> b -> a
const IO ()
rel) IntMap (ReleaseType -> IO ())
m)
, IORef ReleaseMap -> NextKey -> ReleaseKey
ReleaseKey IORef ReleaseMap
istate NextKey
key
)
ReleaseMap
ReleaseMapClosed -> forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> InvalidAccess
InvalidAccess String
"register'"
registerType :: I.IORef ReleaseMap
-> (ReleaseType -> IO ())
-> IO ReleaseKey
registerType :: IORef ReleaseMap -> (ReleaseType -> IO ()) -> IO ReleaseKey
registerType IORef ReleaseMap
istate ReleaseType -> IO ()
rel = forall a b. IORef a -> (a -> (a, b)) -> IO b
I.atomicModifyIORef IORef ReleaseMap
istate forall a b. (a -> b) -> a -> b
$ \ReleaseMap
rm ->
case ReleaseMap
rm of
ReleaseMap NextKey
key RefCount
rf IntMap (ReleaseType -> IO ())
m ->
( NextKey -> RefCount -> IntMap (ReleaseType -> IO ()) -> ReleaseMap
ReleaseMap (NextKey
key forall a. Num a => a -> a -> a
- NextKey
1) RefCount
rf (forall a. NextKey -> a -> IntMap a -> IntMap a
IntMap.insert NextKey
key ReleaseType -> IO ()
rel IntMap (ReleaseType -> IO ())
m)
, IORef ReleaseMap -> NextKey -> ReleaseKey
ReleaseKey IORef ReleaseMap
istate NextKey
key
)
ReleaseMap
ReleaseMapClosed -> forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> InvalidAccess
InvalidAccess String
"register'"
data ResourceCleanupException = ResourceCleanupException
{ ResourceCleanupException -> Maybe SomeException
rceOriginalException :: !(Maybe SomeException)
, ResourceCleanupException -> SomeException
rceFirstCleanupException :: !SomeException
, ResourceCleanupException -> [SomeException]
rceOtherCleanupExceptions :: ![SomeException]
}
deriving (NextKey -> ResourceCleanupException -> ShowS
[ResourceCleanupException] -> ShowS
ResourceCleanupException -> String
forall a.
(NextKey -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResourceCleanupException] -> ShowS
$cshowList :: [ResourceCleanupException] -> ShowS
show :: ResourceCleanupException -> String
$cshow :: ResourceCleanupException -> String
showsPrec :: NextKey -> ResourceCleanupException -> ShowS
$cshowsPrec :: NextKey -> ResourceCleanupException -> ShowS
Show, Typeable)
instance Exception ResourceCleanupException
stateCleanupChecked
:: Maybe SomeException
-> I.IORef ReleaseMap -> IO ()
stateCleanupChecked :: Maybe SomeException -> IORef ReleaseMap -> IO ()
stateCleanupChecked Maybe SomeException
morig IORef ReleaseMap
istate = forall a. IO a -> IO a
E.mask_ forall a b. (a -> b) -> a -> b
$ do
Maybe (IntMap (ReleaseType -> IO ()))
mm <- forall a b. IORef a -> (a -> (a, b)) -> IO b
I.atomicModifyIORef IORef ReleaseMap
istate forall a b. (a -> b) -> a -> b
$ \ReleaseMap
rm ->
case ReleaseMap
rm of
ReleaseMap NextKey
nk RefCount
rf IntMap (ReleaseType -> IO ())
m ->
let rf' :: RefCount
rf' = RefCount
rf forall a. Num a => a -> a -> a
- RefCount
1
in if RefCount
rf' forall a. Eq a => a -> a -> Bool
== forall a. Bounded a => a
minBound
then (ReleaseMap
ReleaseMapClosed, forall a. a -> Maybe a
Just IntMap (ReleaseType -> IO ())
m)
else (NextKey -> RefCount -> IntMap (ReleaseType -> IO ()) -> ReleaseMap
ReleaseMap NextKey
nk RefCount
rf' IntMap (ReleaseType -> IO ())
m, forall a. Maybe a
Nothing)
ReleaseMap
ReleaseMapClosed -> forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> InvalidAccess
InvalidAccess String
"stateCleanupChecked"
case Maybe (IntMap (ReleaseType -> IO ()))
mm of
Just IntMap (ReleaseType -> IO ())
m -> do
[SomeException]
res <- forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeReverseM (\ReleaseType -> IO ()
x -> IO () -> IO (Maybe SomeException)
try (ReleaseType -> IO ()
x ReleaseType
rtype)) forall a b. (a -> b) -> a -> b
$ forall a. IntMap a -> [a]
IntMap.elems IntMap (ReleaseType -> IO ())
m
case [SomeException]
res of
[] -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
SomeException
e:[SomeException]
es -> forall e a. Exception e => e -> IO a
E.throwIO forall a b. (a -> b) -> a -> b
$ Maybe SomeException
-> SomeException -> [SomeException] -> ResourceCleanupException
ResourceCleanupException Maybe SomeException
morig SomeException
e [SomeException]
es
Maybe (IntMap (ReleaseType -> IO ()))
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
try :: IO () -> IO (Maybe SomeException)
try :: IO () -> IO (Maybe SomeException)
try IO ()
io = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> Maybe a
Just (\() -> forall a. Maybe a
Nothing)) (forall e a. Exception e => IO a -> IO (Either e a)
E.try IO ()
io)
rtype :: ReleaseType
rtype = forall b a. b -> (a -> b) -> Maybe a -> b
maybe ReleaseType
ReleaseNormal SomeException -> ReleaseType
ReleaseExceptionWith Maybe SomeException
morig
mapMaybeReverseM :: Monad m => (a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeReverseM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeReverseM a -> m (Maybe b)
f =
[b] -> [a] -> m [b]
go []
where
go :: [b] -> [a] -> m [b]
go [b]
bs [] = forall (m :: * -> *) a. Monad m => a -> m a
return [b]
bs
go [b]
bs (a
a:[a]
as) = do
Maybe b
mb <- a -> m (Maybe b)
f a
a
case Maybe b
mb of
Maybe b
Nothing -> [b] -> [a] -> m [b]
go [b]
bs [a]
as
Just b
b -> [b] -> [a] -> m [b]
go (b
bforall a. a -> [a] -> [a]
:[b]
bs) [a]
as