|
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
|