Blame Control/Concurrent/MVar/Lifted.hs

Packit 1d883e
{-# LANGUAGE CPP
Packit 1d883e
           , NoImplicitPrelude
Packit 1d883e
           , FlexibleContexts
Packit 1d883e
           , TupleSections #-}
Packit 1d883e
Packit 1d883e
#if __GLASGOW_HASKELL__ >= 702
Packit 1d883e
{-# LANGUAGE Safe #-}
Packit 1d883e
#endif
Packit 1d883e
Packit 1d883e
{- |
Packit 1d883e
Module      :  Control.Concurrent.MVar.Lifted
Packit 1d883e
Copyright   :  Bas van Dijk
Packit 1d883e
License     :  BSD-style
Packit 1d883e
Packit 1d883e
Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
Packit 1d883e
Stability   :  experimental
Packit 1d883e
Packit 1d883e
This is a wrapped version of "Control.Concurrent.MVar" with types generalized
Packit 1d883e
from 'IO' to all monads in either 'MonadBase' or 'MonadBaseControl'.
Packit 1d883e
-}
Packit 1d883e
Packit 1d883e
module Control.Concurrent.MVar.Lifted
Packit 1d883e
    ( MVar.MVar
Packit 1d883e
    , newEmptyMVar
Packit 1d883e
    , newMVar
Packit 1d883e
    , takeMVar
Packit 1d883e
    , putMVar
Packit 1d883e
    , readMVar
Packit 1d883e
    , swapMVar
Packit 1d883e
    , tryTakeMVar
Packit 1d883e
    , tryPutMVar
Packit 1d883e
    , isEmptyMVar
Packit 1d883e
    , withMVar
Packit 1d883e
    , modifyMVar_
Packit 1d883e
    , modifyMVar
Packit 1d883e
#if MIN_VERSION_base(4,6,0)
Packit 1d883e
    , modifyMVarMasked_
Packit 1d883e
    , modifyMVarMasked
Packit 1d883e
#endif
Packit 1d883e
#if MIN_VERSION_base(4,6,0)
Packit 1d883e
    , mkWeakMVar
Packit 1d883e
#else
Packit 1d883e
    , addMVarFinalizer
Packit 1d883e
#endif
Packit 1d883e
#if MIN_VERSION_base(4,7,0)
Packit 1d883e
    , withMVarMasked
Packit 1d883e
    , tryReadMVar
Packit 1d883e
#endif
Packit 1d883e
    ) where
Packit 1d883e
Packit 1d883e
Packit 1d883e
--------------------------------------------------------------------------------
Packit 1d883e
-- Imports
Packit 1d883e
--------------------------------------------------------------------------------
Packit 1d883e
Packit 1d883e
-- from base:
Packit 1d883e
import Prelude       ( (.) )
Packit 1d883e
import Data.Bool     ( Bool(False, True) )
Packit 1d883e
import Data.Function ( ($) )
Packit 1d883e
import Data.Functor  ( fmap )
Packit 1d883e
import Data.IORef    ( newIORef, readIORef, writeIORef )
Packit 1d883e
import Data.Maybe    ( Maybe )
Packit 1d883e
import Control.Monad ( return, when )
Packit 1d883e
import System.IO     ( IO )
Packit 1d883e
import           Control.Concurrent.MVar  ( MVar )
Packit 1d883e
import qualified Control.Concurrent.MVar as MVar
Packit 1d883e
import Control.Exception ( onException
Packit 1d883e
#if MIN_VERSION_base(4,3,0)
Packit 1d883e
                         , mask, mask_
Packit 1d883e
#else
Packit 1d883e
                         , block, unblock
Packit 1d883e
#endif
Packit 1d883e
                         )
Packit 1d883e
#if MIN_VERSION_base(4,6,0)
Packit 1d883e
import System.Mem.Weak ( Weak )
Packit 1d883e
#endif
Packit 1d883e
Packit 1d883e
#if __GLASGOW_HASKELL__ < 700
Packit 1d883e
import Control.Monad ( (>>=), (>>), fail )
Packit 1d883e
#endif
Packit 1d883e
Packit 1d883e
-- from transformers-base:
Packit 1d883e
import Control.Monad.Base ( MonadBase, liftBase )
Packit 1d883e
Packit 1d883e
-- from monad-control:
Packit 1d883e
import Control.Monad.Trans.Control ( MonadBaseControl
Packit 1d883e
                                   , control
Packit 1d883e
                                   , liftBaseOp
Packit 1d883e
                                   , liftBaseDiscard
Packit 1d883e
                                   )
Packit 1d883e
Packit 1d883e
#include "inlinable.h"
Packit 1d883e
Packit 1d883e
--------------------------------------------------------------------------------
Packit 1d883e
-- * MVars
Packit 1d883e
--------------------------------------------------------------------------------
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.newEmptyMVar'.
Packit 1d883e
newEmptyMVar :: MonadBase IO m => m (MVar a)
Packit 1d883e
newEmptyMVar = liftBase MVar.newEmptyMVar
Packit 1d883e
{-# INLINABLE newEmptyMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.newMVar'.
Packit 1d883e
newMVar :: MonadBase IO m => a -> m (MVar a)
Packit 1d883e
newMVar = liftBase . MVar.newMVar
Packit 1d883e
{-# INLINABLE newMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.takeMVar'.
Packit 1d883e
takeMVar :: MonadBase IO m => MVar a -> m a
Packit 1d883e
takeMVar = liftBase . MVar.takeMVar
Packit 1d883e
{-# INLINABLE takeMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.putMVar'.
Packit 1d883e
putMVar :: MonadBase IO m => MVar a -> a -> m ()
Packit 1d883e
putMVar mv x = liftBase $ MVar.putMVar mv x
Packit 1d883e
{-# INLINABLE putMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.readMVar'.
Packit 1d883e
readMVar :: MonadBase IO m => MVar a -> m a
Packit 1d883e
readMVar = liftBase . MVar.readMVar
Packit 1d883e
{-# INLINABLE readMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.swapMVar'.
Packit 1d883e
swapMVar :: MonadBase IO m => MVar a -> a -> m a
Packit 1d883e
swapMVar mv x = liftBase $ MVar.swapMVar mv x
Packit 1d883e
{-# INLINABLE swapMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.tryTakeMVar'.
Packit 1d883e
tryTakeMVar :: MonadBase IO m => MVar a -> m (Maybe a)
Packit 1d883e
tryTakeMVar = liftBase . MVar.tryTakeMVar
Packit 1d883e
{-# INLINABLE tryTakeMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.tryPutMVar'.
Packit 1d883e
tryPutMVar :: MonadBase IO m => MVar a -> a -> m Bool
Packit 1d883e
tryPutMVar mv x = liftBase $ MVar.tryPutMVar mv x
Packit 1d883e
{-# INLINABLE tryPutMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.isEmptyMVar'.
Packit 1d883e
isEmptyMVar :: MonadBase IO m => MVar a -> m Bool
Packit 1d883e
isEmptyMVar = liftBase . MVar.isEmptyMVar
Packit 1d883e
{-# INLINABLE isEmptyMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.withMVar'.
Packit 1d883e
withMVar :: MonadBaseControl IO m => MVar a -> (a -> m b) -> m b
Packit 1d883e
withMVar = liftBaseOp . MVar.withMVar
Packit 1d883e
{-# INLINABLE withMVar #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.modifyMVar_'.
Packit 1d883e
modifyMVar_ :: (MonadBaseControl IO m) => MVar a -> (a -> m a) -> m ()
Packit 1d883e
modifyMVar_ mv = modifyMVar mv . (fmap (, ()) .)
Packit 1d883e
{-# INLINABLE modifyMVar_ #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.modifyMVar'.
Packit 1d883e
modifyMVar :: (MonadBaseControl IO m) => MVar a -> (a -> m (a, b)) -> m b
Packit 1d883e
Packit 1d883e
#if MIN_VERSION_base(4,3,0)
Packit 1d883e
modifyMVar mv f = control $ \runInIO -> mask $ \restore -> do
Packit 1d883e
    aborted <- newIORef True
Packit 1d883e
    let f' x = do
Packit 1d883e
        (x', a) <- f x
Packit 1d883e
        liftBase $ mask_ $ do
Packit 1d883e
          writeIORef aborted False
Packit 1d883e
          MVar.putMVar mv x'
Packit 1d883e
        return a
Packit 1d883e
    x <- MVar.takeMVar mv
Packit 1d883e
    stM <- restore (runInIO (f' x)) `onException` MVar.putMVar mv x
Packit 1d883e
    abort <- readIORef aborted
Packit 1d883e
    when abort $ MVar.putMVar mv x
Packit 1d883e
    return stM
Packit 1d883e
#else
Packit 1d883e
modifyMVar mv f = control $ \runInIO -> block $ do
Packit 1d883e
    aborted <- newIORef True
Packit 1d883e
    let f' x = do
Packit 1d883e
        (x', a) <- f x
Packit 1d883e
        liftBase $ block $ do
Packit 1d883e
          writeIORef aborted False
Packit 1d883e
          MVar.putMVar mv x'
Packit 1d883e
        return a
Packit 1d883e
    x <- MVar.takeMVar mv
Packit 1d883e
    stM <- unblock (runInIO (f' x)) `onException` MVar.putMVar mv x
Packit 1d883e
    abort <- readIORef aborted
Packit 1d883e
    when abort $ MVar.putMVar mv x
Packit 1d883e
    return stM
Packit 1d883e
#endif
Packit 1d883e
{-# INLINABLE modifyMVar #-}
Packit 1d883e
Packit 1d883e
#if MIN_VERSION_base(4,6,0)
Packit 1d883e
-- | Generalized version of 'MVar.modifyMVarMasked_'.
Packit 1d883e
modifyMVarMasked_ :: (MonadBaseControl IO m) => MVar a -> (a -> m a) -> m ()
Packit 1d883e
modifyMVarMasked_ mv = modifyMVarMasked mv . (fmap (, ()) .)
Packit 1d883e
{-# INLINABLE modifyMVarMasked_ #-}
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.modifyMVarMasked'.
Packit 1d883e
modifyMVarMasked :: (MonadBaseControl IO m) => MVar a -> (a -> m (a, b)) -> m b
Packit 1d883e
modifyMVarMasked mv f = control $ \runInIO -> mask_ $ do
Packit 1d883e
    aborted <- newIORef True
Packit 1d883e
    let f' x = do
Packit 1d883e
        (x', a) <- f x
Packit 1d883e
        liftBase $ do
Packit 1d883e
          writeIORef aborted False
Packit 1d883e
          MVar.putMVar mv x'
Packit 1d883e
        return a
Packit 1d883e
    x <- MVar.takeMVar mv
Packit 1d883e
    stM <- runInIO (f' x) `onException` MVar.putMVar mv x
Packit 1d883e
    abort <- readIORef aborted
Packit 1d883e
    when abort $ MVar.putMVar mv x
Packit 1d883e
    return stM
Packit 1d883e
{-# INLINABLE modifyMVarMasked #-}
Packit 1d883e
#endif
Packit 1d883e
Packit 1d883e
#if MIN_VERSION_base(4,6,0)
Packit 1d883e
-- | Generalized version of 'MVar.mkWeakMVar'.
Packit 1d883e
--
Packit 1d883e
-- Note any monadic side effects in @m@ of the \"finalizer\" computation are
Packit 1d883e
-- discarded.
Packit 1d883e
mkWeakMVar :: MonadBaseControl IO m => MVar a -> m () -> m (Weak (MVar a))
Packit 1d883e
mkWeakMVar = liftBaseDiscard . MVar.mkWeakMVar
Packit 1d883e
{-# INLINABLE mkWeakMVar #-}
Packit 1d883e
#else
Packit 1d883e
-- | Generalized version of 'MVar.addMVarFinalizer'.
Packit 1d883e
--
Packit 1d883e
-- Note any monadic side effects in @m@ of the \"finalizer\" computation are
Packit 1d883e
-- discarded.
Packit 1d883e
addMVarFinalizer :: MonadBaseControl IO m => MVar a -> m () -> m ()
Packit 1d883e
addMVarFinalizer = liftBaseDiscard . MVar.addMVarFinalizer
Packit 1d883e
{-# INLINABLE addMVarFinalizer #-}
Packit 1d883e
#endif
Packit 1d883e
Packit 1d883e
#if MIN_VERSION_base (4,7,0)
Packit 1d883e
-- | Generalized version of 'MVar.withMVarMasked'.
Packit 1d883e
withMVarMasked :: MonadBaseControl IO m => MVar a -> (a -> m b) -> m b
Packit 1d883e
withMVarMasked = liftBaseOp . MVar.withMVarMasked
Packit 1d883e
Packit 1d883e
-- | Generalized version of 'MVar.tryReadMVar'.
Packit 1d883e
tryReadMVar :: MonadBase IO m => MVar a -> m (Maybe a)
Packit 1d883e
tryReadMVar = liftBase . MVar.tryReadMVar
Packit 1d883e
#endif