packages feed

resourcet 1.1.11 → 1.2.0

raw patch · 7 files changed

+83/−256 lines, 7 filesdep +primitivedep −lifted-basedep −mmorphdep −monad-controldep ~basedep ~exceptionsdep ~transformersPVP ok

version bump matches the API change (PVP)

Dependencies added: primitive

Dependencies removed: lifted-base, mmorph, monad-control, transformers-base, transformers-compat

Dependency ranges changed: base, exceptions, transformers

API changes (from Hackage documentation)

- Control.Monad.Trans.Resource: class MonadBase b m => MonadBaseControl (b :: * -> *) (m :: * -> *) | m -> b
- Control.Monad.Trans.Resource: monadThrow :: (Exception e, MonadThrow m) => e -> m a
- Control.Monad.Trans.Resource: runException :: ExceptionT Identity a -> Either SomeException a
- Control.Monad.Trans.Resource: runExceptionT :: ExceptionT m a -> m (Either SomeException a)
- Control.Monad.Trans.Resource: runExceptionT_ :: Monad m => ExceptionT m a -> m a
- Control.Monad.Trans.Resource: runException_ :: ExceptionT Identity a -> a
- Control.Monad.Trans.Resource: type ExceptionT = CatchT
- Control.Monad.Trans.Resource.Internal: instance (Control.Monad.Catch.MonadThrow m, Control.Monad.Base.MonadBase GHC.Types.IO m, Control.Monad.IO.Class.MonadIO m, GHC.Base.Applicative m) => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Resource.Internal.ResourceT m)
- Control.Monad.Trans.Resource.Internal: instance (Control.Monad.Trans.Error.Error e, Control.Monad.Trans.Resource.Internal.MonadResource m) => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Error.ErrorT e m)
- Control.Monad.Trans.Resource.Internal: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Control.Monad.Trans.Resource.Internal.ResourceT m)
- Control.Monad.Trans.Resource.Internal: instance Control.Monad.Morph.MFunctor Control.Monad.Trans.Resource.Internal.ResourceT
- Control.Monad.Trans.Resource.Internal: instance Control.Monad.Morph.MMonad Control.Monad.Trans.Resource.Internal.ResourceT
- Control.Monad.Trans.Resource.Internal: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Control.Monad.Trans.Resource.Internal.ResourceT m)
- Control.Monad.Trans.Resource.Internal: instance Control.Monad.Trans.Control.MonadTransControl Control.Monad.Trans.Resource.Internal.ResourceT
- Data.Acquire: withEx :: (MonadMask m, MonadIO m) => Acquire a -> (a -> m b) -> m b
- Data.Acquire.Internal: instance Control.Monad.Base.MonadBase GHC.Types.IO Data.Acquire.Internal.Acquire
- Data.Acquire.Internal: withEx :: (MonadMask m, MonadIO m) => Acquire a -> (a -> m b) -> m b
+ Control.Monad.Trans.Resource: class MonadIO m => MonadUnliftIO (m :: * -> *)
+ Control.Monad.Trans.Resource.Internal: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Resource.Internal.ResourceT m)
+ Control.Monad.Trans.Resource.Internal: instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Control.Monad.Trans.Resource.Internal.ResourceT m)
+ Data.Acquire: withAcquire :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b
- Control.Monad.Trans.Resource: class (MonadThrow m, MonadIO m, Applicative m, MonadBase IO m) => MonadResource m
+ Control.Monad.Trans.Resource: class MonadIO m => MonadResource m
- Control.Monad.Trans.Resource: closeInternalState :: MonadBase IO m => InternalState -> m ()
+ Control.Monad.Trans.Resource: closeInternalState :: MonadIO m => InternalState -> m ()
- Control.Monad.Trans.Resource: createInternalState :: MonadBase IO m => m InternalState
+ Control.Monad.Trans.Resource: createInternalState :: MonadIO m => m InternalState
- Control.Monad.Trans.Resource: resourceForkIO :: MonadBaseControl IO m => ResourceT m () -> ResourceT m ThreadId
+ Control.Monad.Trans.Resource: resourceForkIO :: MonadUnliftIO m => ResourceT m () -> ResourceT m ThreadId
- Control.Monad.Trans.Resource: resourceForkWith :: MonadBaseControl IO m => (IO () -> IO a) -> ResourceT m () -> ResourceT m a
+ Control.Monad.Trans.Resource: resourceForkWith :: MonadUnliftIO m => (IO () -> IO a) -> ResourceT m () -> ResourceT m a
- Control.Monad.Trans.Resource: runResourceT :: MonadBaseControl IO m => ResourceT m a -> m a
+ Control.Monad.Trans.Resource: runResourceT :: MonadUnliftIO m => ResourceT m a -> m a
- Control.Monad.Trans.Resource: type MonadResourceBase m = (MonadBaseControl IO m, MonadThrow m, MonadBase IO m, MonadIO m, Applicative m)
+ Control.Monad.Trans.Resource: type MonadResourceBase = MonadUnliftIO
- Control.Monad.Trans.Resource.Internal: class (MonadThrow m, MonadIO m, Applicative m, MonadBase IO m) => MonadResource m
+ Control.Monad.Trans.Resource.Internal: class MonadIO m => MonadResource m
- Data.Acquire: with :: MonadBaseControl IO m => Acquire a -> (a -> m b) -> m b
+ Data.Acquire: with :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b
- Data.Acquire.Internal: with :: MonadBaseControl IO m => Acquire a -> (a -> m b) -> m b
+ Data.Acquire.Internal: with :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b

Files

ChangeLog.md view
@@ -1,3 +1,8 @@+## 1.2.0++* Drop `monad-control` and `mmorph` dependencies+* Change behavior of `runResourceT` to match `runResourceTChecked`+ ## 1.1.11  * `runResourceTChecked`, which checks if any of the cleanup actions
Control/Monad/Trans/Resource.hs view
@@ -6,10 +6,7 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-}-#if __GLASGOW_HASKELL__ >= 704 {-# LANGUAGE ConstraintKinds #-}-#endif-{-# LANGUAGE Safe #-} -- | Allocate resources which are guaranteed to be released. -- -- For more information, see <https://www.fpcomplete.com/user/snoyberg/library-documentation/resourcet>.@@ -45,7 +42,7 @@       -- ** Low-level     , InvalidAccess (..)       -- * Re-exports-    , MonadBaseControl+    , MonadUnliftIO       -- * Internal state       -- $internalState     , InternalState@@ -54,36 +51,20 @@     , withInternalState     , createInternalState     , closeInternalState-      -- * Backwards compatibility-    , ExceptionT (..)-    , runExceptionT-    , runExceptionT_-    , runException-    , runException_+      -- * Reexport     , MonadThrow (..)-    , monadThrow     ) where  import qualified Data.IntMap as IntMap-import Control.Exception (SomeException, throw)-import Control.Monad.Trans.Control-    ( MonadBaseControl (..), liftBaseDiscard, control ) import qualified Data.IORef as I-import Control.Monad.Base (MonadBase, liftBase)-import Control.Applicative (Applicative (..)) import Control.Monad.IO.Unlift (MonadIO (..), MonadUnliftIO, withRunInIO)-import Control.Monad (liftM) import qualified Control.Exception as E-import Data.Monoid (Monoid)-import qualified Control.Exception.Lifted as L  import Control.Monad.Trans.Resource.Internal  import Control.Concurrent (ThreadId, forkIO) -import Data.Functor.Identity (Identity, runIdentity) import Control.Monad.Catch (MonadThrow, throwM)-import Control.Monad.Catch.Pure (CatchT, runCatchT) import Data.Acquire.Internal (ReleaseType (..))  @@ -183,28 +164,13 @@ -- If multiple threads are sharing the same collection of resources, only the -- last call to @runResourceT@ will deallocate the resources. ----- /NOTE/ Since version 1.1.11, this module has also provided--- `runResourceTChecked`, which is a safer version of this--- function. In the next major release of this library, it will become--- the behavior of this function.------ Since 0.3.0-runResourceT :: MonadBaseControl IO m => ResourceT m a -> m a-runResourceT (ResourceT r) = control $ \run -> do-    istate <- createInternalState-    E.mask $ \restore -> do-        res <- restore (run (r istate)) `E.onException`-            stateCleanup ReleaseException istate-        stateCleanup ReleaseNormal istate-        return res---- | Like 'runResourceT', but checks whether the cleanup functions--- throw any exceptions. If they do, they are rethrown inside a--- 'ResourceCleanupException'.+-- /NOTE/ Since version 1.2.0, this function will throw a+-- 'ResourceCleanupException' if any of the cleanup functions throw an+-- exception. ----- @since 1.1.11-runResourceTChecked :: MonadUnliftIO m => ResourceT m a -> m a-runResourceTChecked (ResourceT r) = withRunInIO $ \run -> do+-- @since 0.3.0+runResourceT :: MonadUnliftIO m => ResourceT m a -> m a+runResourceT (ResourceT r) = withRunInIO $ \run -> do     istate <- createInternalState     E.mask $ \restore -> do         res <- restore (run (r istate)) `E.catch` \e -> do@@ -213,23 +179,26 @@         stateCleanupChecked Nothing istate         return res -bracket_ :: MonadBaseControl IO m+-- | Backwards compatible alias for 'runResourceT'.+--+-- @since 1.1.11+runResourceTChecked :: MonadUnliftIO m => ResourceT m a -> m a+runResourceTChecked = runResourceT+{-# INLINE runResourceTChecked #-}++bracket_ :: MonadUnliftIO m          => IO () -- ^ allocate          -> IO () -- ^ normal cleanup          -> IO () -- ^ exceptional cleanup          -> m a          -> m a bracket_ alloc cleanupNormal cleanupExc inside =-    control $ \run -> E.mask $ \restore -> do+    withRunInIO $ \run -> E.mask $ \restore -> do         alloc         res <- restore (run inside) `E.onException` cleanupExc         cleanupNormal         return res -finally :: MonadBaseControl IO m => m a -> IO () -> m a-finally action cleanup =-    control $ \run -> E.finally (run action) cleanup- -- | This function mirrors @join@ at the transformer level: it will collapse -- two levels of @ResourceT@ into a single @ResourceT@. --@@ -238,31 +207,6 @@               -> ResourceT m a joinResourceT (ResourceT f) = ResourceT $ \r -> unResourceT (f r) r --- | For backwards compatibility.-type ExceptionT = CatchT---- | For backwards compatibility.-runExceptionT :: ExceptionT m a -> m (Either SomeException a)-runExceptionT = runCatchT---- | Same as 'runExceptionT', but immediately 'E.throw' any exception returned.------ Since 0.3.0-runExceptionT_ :: Monad m => ExceptionT m a -> m a-runExceptionT_ = liftM (either E.throw id) . runExceptionT---- | Run an @ExceptionT Identity@ stack.------ Since 0.4.2-runException :: ExceptionT Identity a -> Either SomeException a-runException = runIdentity . runExceptionT---- | Run an @ExceptionT Identity@ stack, but immediately 'E.throw' any exception returned.------ Since 0.4.2-runException_ :: ExceptionT Identity a -> a-runException_ = runIdentity . runExceptionT_- -- | 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.@@ -279,8 +223,13 @@ -- a new @ResourceT@ block and then call @resourceForkWith@ from there. -- -- @since 1.1.9-resourceForkWith :: MonadBaseControl IO m => (IO () -> IO a) -> ResourceT m () -> ResourceT m a-resourceForkWith g (ResourceT f) = ResourceT $ \r -> L.mask $ \restore ->+resourceForkWith+  :: MonadUnliftIO m+  => (IO () -> IO a)+  -> ResourceT m ()+  -> ResourceT m a+resourceForkWith g (ResourceT f) =+  ResourceT $ \r -> withRunInIO $ \run -> E.mask $ \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@@ -289,46 +238,35 @@         (stateAlloc r)         (return ())         (return ())-        (liftBaseDiscard g $ bracket_+        (g $ bracket_             (return ())             (stateCleanup ReleaseNormal r)             (stateCleanup ReleaseException r)-            (restore $ f r))+            (restore $ run $ f r))  -- | Launch a new reference counted resource context using @forkIO@. -- -- This is defined as @resourceForkWith forkIO@. -- -- @since 0.3.0-resourceForkIO :: MonadBaseControl IO m => ResourceT m () -> ResourceT m ThreadId+resourceForkIO :: MonadUnliftIO m => ResourceT m () -> ResourceT m ThreadId resourceForkIO = resourceForkWith forkIO --- | A @Monad@ which can be used as a base for a @ResourceT@.------ A @ResourceT@ has some restrictions on its base monad:+-- | Just use 'MonadUnliftIO' directly now, legacy explanation continues: ----- * @runResourceT@ requires an instance of @MonadBaseControl IO@.--- * @MonadResource@ requires an instance of @MonadThrow@, @MonadIO@, and @Applicative@.+-- A @Monad@ which can be used as a base for a @ResourceT@. ----- While any instance of @MonadBaseControl IO@ should be an instance of the--- other classes, this is not guaranteed by the type system (e.g., you may have--- a transformer in your stack with does not implement @MonadThrow@). Ideally,--- we would like to simply create an alias for the five type classes listed,--- but this is not possible with GHC currently.+-- A @ResourceT@ has some restrictions on its base monad: ----- Instead, this typeclass acts as a proxy for the other five. Its only purpose--- is to make your type signatures shorter.+-- * @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-#if __GLASGOW_HASKELL__ >= 704-type MonadResourceBase m = (MonadBaseControl IO m, MonadThrow m, MonadBase IO m, MonadIO m, Applicative m)-#else-class (MonadBaseControl IO m, MonadThrow m, MonadIO m, Applicative m) => MonadResourceBase m-instance (MonadBaseControl IO m, MonadThrow m, MonadIO m, Applicative m) => MonadResourceBase m-#endif+type MonadResourceBase = MonadUnliftIO+{-# DEPRECATED MonadResourceBase "Use MonadUnliftIO directly instead" #-}  -- $internalState --@@ -344,16 +282,16 @@ -- Caveat emptor! -- -- Since 0.4.9-createInternalState :: MonadBase IO m => m InternalState-createInternalState = liftBase+createInternalState :: MonadIO m => m InternalState+createInternalState = liftIO                     $ I.newIORef                     $ ReleaseMap maxBound (minBound + 1) IntMap.empty  -- | Close an internal state created by @createInternalState@. -- -- Since 0.4.9-closeInternalState :: MonadBase IO m => InternalState -> m ()-closeInternalState = liftBase . stateCleanup ReleaseNormal+closeInternalState :: MonadIO m => InternalState -> m ()+closeInternalState = liftIO . stateCleanup ReleaseNormal  -- | Get the internal state of the current @ResourceT@. --@@ -377,7 +315,3 @@ -- Since 0.4.6 withInternalState :: (InternalState -> m a) -> ResourceT m a withInternalState = ResourceT---- | Backwards compatibility-monadThrow :: (E.Exception e, MonadThrow m) => e -> m a-monadThrow = throwM
Control/Monad/Trans/Resource/Internal.hs view
@@ -7,13 +7,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE RankNTypes #-}--- Can only mark as Safe when using a newer GHC, otherwise we get build--- failures due to the manual Typeable instance below.-#if __GLASGOW_HASKELL__ >= 707-{-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif  module Control.Monad.Trans.Resource.Internal(     InvalidAccess(..)@@ -36,9 +29,7 @@ import Control.Monad (MonadPlus(..)) import Control.Monad.Fix (MonadFix(..)) import Control.Monad.IO.Unlift-import Control.Monad.Trans.Control-    ( MonadTransControl (..), MonadBaseControl (..) )-import Control.Monad.Base (MonadBase, liftBase)+import Control.Monad.Trans.Class    (MonadTrans (..)) import Control.Monad.Trans.Cont     ( ContT  ) import Control.Monad.Cont.Class   ( MonadCont (..) ) import Control.Monad.Error.Class  ( MonadError (..) )@@ -50,7 +41,6 @@ import Control.Monad.Trans.Identity ( IdentityT) import Control.Monad.Trans.List     ( ListT    ) import Control.Monad.Trans.Maybe    ( MaybeT   )-import Control.Monad.Trans.Error    ( ErrorT, Error) import Control.Monad.Trans.Except   ( ExceptT  ) import Control.Monad.Trans.Reader   ( ReaderT  ) import Control.Monad.Trans.State    ( StateT   )@@ -62,38 +52,30 @@ import qualified Control.Monad.Trans.Writer.Strict as Strict ( WriterT )  import Control.Monad.IO.Class (MonadIO (..))-#if !(MIN_VERSION_monad_control(1,0,0))-import Control.Monad (liftM)-#endif+import Control.Monad.Primitive (PrimMonad (..)) import qualified Control.Exception as E-import Control.Monad.Catch (MonadThrow (..), MonadCatch (..)-#if MIN_VERSION_exceptions(0,6,0)-    , MonadMask (..)-#endif-    )++-- FIXME Do we want to only support MonadThrow?+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.Monoid import Data.Typeable import Data.Word(Word)-import Prelude hiding (catch) import Data.Acquire.Internal (ReleaseType (..)) -import Control.Monad.Morph- -- | A @Monad@ which allows for safe resource allocation. In theory, any monad -- transformer stack which includes a @ResourceT@ can be an instance of -- @MonadResource@. ----- Note: @runResourceT@ has a requirement for a @MonadBaseControl IO m@ monad,+-- Note: @runResourceT@ has a requirement for a @MonadUnliftIO m@ monad, -- which allows control operations to be lifted. A @MonadResource@ does not -- have this requirement. This means that transformers such as @ContT@ can be -- an instance of @MonadResource@. However, the @ContT@ wrapper will need to be -- unwrapped before calling @runResourceT@. -- -- Since 0.3.0-class (MonadThrow m, MonadIO m, Applicative m, MonadBase IO m) => MonadResource m where+class MonadIO m => MonadResource m where     -- | Lift a @ResourceT IO@ action into the current @Monad@.     --     -- Since 0.4.0@@ -148,16 +130,17 @@ instance MonadCatch m => MonadCatch (ResourceT m) where   catch (ResourceT m) c =       ResourceT $ \r -> m r `catch` \e -> unResourceT (c e) r-#if MIN_VERSION_exceptions(0,6,0) instance MonadMask m => MonadMask (ResourceT m) where-#endif   mask a = ResourceT $ \e -> mask $ \u -> unResourceT (a $ q u) e     where q u (ResourceT b) = ResourceT (u . b)   uninterruptibleMask a =     ResourceT $ \e -> uninterruptibleMask $ \u -> unResourceT (a $ q u) e       where q u (ResourceT b) = ResourceT (u . b)-instance (MonadThrow m, MonadBase IO m, MonadIO m, Applicative m) => MonadResource (ResourceT m) where+instance MonadIO m => MonadResource (ResourceT m) where     liftResourceT = transResourceT liftIO+instance PrimMonad m => PrimMonad (ResourceT m) where+    type PrimState (ResourceT m) = PrimState m+    primitive = lift . primitive  -- | Transform the monad a @ResourceT@ lives in. This is most often used to -- strip or add new transformers to a stack, e.g. to run a @ReaderT@.@@ -170,13 +153,6 @@                -> ResourceT n b transResourceT f (ResourceT mx) = ResourceT (\r -> f (mx r)) --- | Since 0.4.7-instance MFunctor ResourceT where-    hoist f (ResourceT mx) = ResourceT (\r -> f (mx r))--- | Since 0.4.7-instance MMonad ResourceT where-    embed f m = ResourceT (\i -> unResourceT (f (unResourceT m i)) i)- -- | The Resource transformer. This transformer keeps track of all registered -- actions, and calls them upon exit (via 'runResourceT'). Actions may be -- registered via 'register', or resources may be allocated atomically via@@ -243,9 +219,7 @@     (ResourceT mf) `mplus` (ResourceT ma) = ResourceT $ \r -> mf r `mplus` ma r  instance Monad m => Monad (ResourceT m) where-#if !MIN_VERSION_base(4,8,0)-    return = ResourceT . const . return-#endif+    return = pure     ResourceT ma >>= f = ResourceT $ \r -> do         a <- ma r         let ResourceT f' = f a@@ -261,37 +235,6 @@ instance MonadIO m => MonadIO (ResourceT m) where     liftIO = lift . liftIO -instance MonadBase b m => MonadBase b (ResourceT m) where-    liftBase = lift . liftBase--instance MonadTransControl ResourceT where-#if MIN_VERSION_monad_control(1,0,0)-    type StT ResourceT a = a-    liftWith f = ResourceT $ \r -> f $ \(ResourceT t) -> t r-    restoreT = ResourceT . const-#else-    newtype StT ResourceT a = StReader {unStReader :: a}-    liftWith f = ResourceT $ \r -> f $ \(ResourceT t) -> liftM StReader $ t r-    restoreT = ResourceT . const . liftM unStReader-#endif-    {-# INLINE liftWith #-}-    {-# INLINE restoreT #-}--instance MonadBaseControl b m => MonadBaseControl b (ResourceT m) where-#if MIN_VERSION_monad_control(1,0,0)-     type StM (ResourceT m) a = StM m a-     liftBaseWith f = ResourceT $ \reader' ->-         liftBaseWith $ \runInBase ->-             f $ runInBase . (\(ResourceT r) -> r reader'  )-     restoreM = ResourceT . const . restoreM-#else-     newtype StM (ResourceT m) a = StMT (StM m a)-     liftBaseWith f = ResourceT $ \reader' ->-         liftBaseWith $ \runInBase ->-             f $ liftM StMT . runInBase . (\(ResourceT r) -> r reader'  )-     restoreM (StMT base) = ResourceT $ const $ restoreM base-#endif- -- | @since 1.1.10 instance MonadUnliftIO m => MonadUnliftIO (ResourceT m) where   askUnliftIO = ResourceT $ \r ->@@ -303,10 +246,7 @@ GO(IdentityT) GO(ListT) GO(MaybeT)-GOX(Error e, ErrorT e)-#if MIN_VERSION_exceptions(0, 8, 0) GO(ExceptT e)-#endif GO(ReaderT r) GO(ContT r) GO(StateT s)
Data/Acquire.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE Safe #-} -- | This was previously known as the Resource monad. However, that term is -- confusing next to the ResourceT transformer, so it has been renamed. @@ -61,7 +60,7 @@ -- > code.hs: divide by zero --     , with-    , withEx+    , withAcquire     , mkAcquire     , mkAcquireType     , allocateAcquire@@ -69,15 +68,9 @@     ) where  import Control.Monad.Trans.Resource.Internal-import Control.Monad.Trans.Resource import Data.Acquire.Internal-import Control.Applicative (Applicative (..))-import Control.Monad.Base (MonadBase (..))-import Control.Monad.IO.Class (MonadIO (..))-import Control.Monad.Trans.Control (MonadBaseControl, control)-import qualified Control.Exception.Lifted as E-import Data.Typeable (Typeable)-import Control.Monad (liftM, ap)+import Control.Monad.IO.Unlift (MonadIO (..), MonadUnliftIO)+import qualified Control.Exception as E  -- | Allocate a resource and register an action with the @MonadResource@ to -- free the resource.@@ -91,3 +84,10 @@     Allocated a free <- f restore     key <- registerType istate free     return (key, a)++-- | Longer name for 'with', in case @with@ is not obvious enough in context.+--+-- @since 1.2.0+withAcquire :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b+withAcquire = with+{-# INLINE withAcquire #-}
Data/Acquire/Internal.hs view
@@ -4,26 +4,21 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE Trustworthy #-} module Data.Acquire.Internal     ( Acquire (..)     , Allocated (..)     , with-    , withEx     , mkAcquire     , ReleaseType (..)     , mkAcquireType     ) where  import Control.Applicative (Applicative (..))-import Control.Monad.Base (MonadBase (..))-import Control.Monad.IO.Class (MonadIO (..))-import Control.Monad.Trans.Control (MonadBaseControl, control)-import qualified Control.Exception.Lifted as E+import Control.Monad.IO.Unlift (MonadIO (..), MonadUnliftIO, withRunInIO)+import qualified Control.Exception as E import Data.Typeable (Typeable) import Control.Monad (liftM, ap)-import qualified Control.Monad.Catch as C-import GHC.IO (unsafeUnmask)+import qualified Control.Monad.Catch as C ()  -- | The way in which a release is called. --@@ -69,9 +64,6 @@         x <- restore f         return $! Allocated x (const $ return ()) -instance MonadBase IO Acquire where-    liftBase = liftIO- -- | Create an @Acquire@ value using the given allocate and free functions. -- -- @since 1.1.0@@ -101,39 +93,12 @@ -- @bracket@. -- -- @since 1.1.0-with :: MonadBaseControl IO m+with :: MonadUnliftIO m      => Acquire a      -> (a -> m b)      -> m b-with (Acquire f) g = control $ \run -> E.mask $ \restore -> do+with (Acquire f) g = withRunInIO $ \run -> E.mask $ \restore -> do     Allocated x free <- f restore     res <- restore (run (g x)) `E.onException` free ReleaseException     free ReleaseNormal     return res---- | Same as @with@, but uses the @MonadMask@ typeclass from exceptions instead--- of @MonadBaseControl@ from exceptions.------ @since 1.1.3-#if MIN_VERSION_exceptions(0,6,0)-withEx :: (C.MonadMask m, MonadIO m)-#else-withEx :: (C.MonadCatch m, MonadIO m)-#endif-       => Acquire a-       -> (a -> m b)-       -> m b-withEx (Acquire f) g = do-    -- We need to do some funny business, since the restore we get below is-    -- specialized to the m from the result, whereas we need a restore function-    -- in IO. Checking the current masking state is exactly how mask is-    -- implemented in base.-    origMS <- liftIO E.getMaskingState--    C.mask $ \restore -> do-        Allocated x free <- liftIO $ f $ case origMS of-            E.Unmasked -> unsafeUnmask-            _ -> id-        res <- restore (g x) `C.onException` liftIO (free ReleaseException)-        liftIO $ free ReleaseNormal-        return res
resourcet.cabal view
@@ -1,5 +1,5 @@ Name:                resourcet-Version:             1.1.11+Version:             1.2.0 Synopsis:            Deterministic allocation and freeing of scarce resources. description:         Hackage documentation generation is not reliable. For up to date documentation, please see: <http://www.stackage.org/package/resourcet>. License:             BSD3@@ -18,17 +18,13 @@                        Data.Acquire                        Data.Acquire.Internal                        UnliftIO.Resource-  Build-depends:       base                     >= 4.5          && < 5-                     , lifted-base              >= 0.1-                     , transformers-base        >= 0.4.4        && < 0.5-                     , monad-control            >= 0.3.1        && < 1.1+  Build-depends:       base                     >= 4.9          && < 5                      , containers-                     , transformers             >= 0.2.2-                     , transformers-compat      >= 0.3          && < 0.6+                     , transformers             >= 0.4                      , mtl                      >= 2.0          && < 2.3-                     , mmorph-                     , exceptions               >= 0.5+                     , exceptions               >= 0.8                      , unliftio-core+                     , primitive   ghc-options:     -Wall  test-suite test@@ -39,7 +35,6 @@     build-depends:   resourcet                    , base                    , hspec >= 1.3-                   , lifted-base                    , transformers     ghc-options:     -Wall 
test/main.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE ScopedTypeVariables #-}  import           Control.Concurrent-import           Control.Concurrent.Lifted    (fork) import           Control.Exception            (Exception, MaskingState (MaskedInterruptible),                                                getMaskingState, throwIO, try, fromException) import           Control.Exception            (SomeException, handle)@@ -18,7 +17,7 @@ main = hspec $ do     describe "general" $ do         it "survives releasing bottom" $ do-            x <- newIORef 0+            x <- newIORef (0 :: Int)             handle (\(_ :: SomeException) -> return ()) $ runResourceT $ do                 _ <- register $ writeIORef x 1                 release undefined@@ -26,7 +25,7 @@             x' `shouldBe` 1     describe "early release" $ do         it "works from a different context" $ do-            x <- newIORef 0+            x <- newIORef (0 :: Int)             runResourceT $ do                 key <- register $ writeIORef x 1                 runResourceT $ release key@@ -35,11 +34,11 @@     describe "resourceForkIO" $ do         it "waits for all threads" $ do             x <- newEmptyMVar-            y <- newIORef 0+            y <- newIORef (0 :: Int)             z <- newEmptyMVar             w <- newEmptyMVar -            runResourceT $ do+            _ <- runResourceT $ do                 _ <- register $ do                     writeIORef y 1                     putMVar w ()@@ -62,8 +61,8 @@             Just y2 `shouldBe` Just 1     describe "unprotecting" $ do         it "unprotect keeps resource from being cleared" $ do-            x <- newIORef 0-            runResourceT $ do+            x <- newIORef (0 :: Int)+            _ <- runResourceT $ do               key <- register $ writeIORef x 1               unprotect key             y <- readIORef x@@ -73,11 +72,11 @@                 ms <- getMaskingState                 unless (ms == MaskedInterruptible) $                     error $ show (name, ms)-        runResourceT $ do+        _ <- runResourceT $ do             register (checkMasked "release") >>= release             register (checkMasked "normal")         Left Dummy <- try $ runResourceT $ do-            register (checkMasked "exception")+            _ <- register (checkMasked "exception")             liftIO $ throwIO Dummy         return ()     describe "mkAcquireType" $ do@@ -113,17 +112,6 @@                 ref <- newIORef Nothing                 let acq = mkAcquireType (return ()) $ \() -> writeIORef ref . Just                 Left Dummy <- try $ with acq $ const $ throwIO Dummy-                readIORef ref >>= (`shouldBe` Just ReleaseException)-        describe "withEx" $ do-            it "normal" $ do-                ref <- newIORef Nothing-                let acq = mkAcquireType (return ()) $ \() -> writeIORef ref . Just-                withEx acq $ const $ return ()-                readIORef ref >>= (`shouldBe` Just ReleaseNormal)-            it "exception" $ do-                ref <- newIORef Nothing-                let acq = mkAcquireType (return ()) $ \() -> writeIORef ref . Just-                Left Dummy <- try $ withEx acq $ const $ throwIO Dummy                 readIORef ref >>= (`shouldBe` Just ReleaseException)     describe "runResourceTChecked" $ do         it "catches exceptions" $ do