-- | For full documentation please refer to "Control.Concurrent.MVar".
module Control.Concurrent.MVar.Strict
  ( MVar'

    -- * Operations
  , newEmptyMVar'
  , newMVar'
  , takeMVar'
  , putMVar'
  , readMVar'
  , swapMVar'
  , tryTakeMVar'
  , tryPutMVar'
  , tryReadMVar'
  , isEmptyMVar'
  , withMVar'
  , withMVar'Masked
  , modifyMVar'_
  , modifyMVar'
  , modifyMVar'Masked_
  , modifyMVar'Masked
  , mkWeakMVar'
  ) where

import Control.DeepSeq
import Control.Exception (evaluate)
import GHC.Exts (mkWeak#)
import GHC.IO (IO(..))
import GHC.MVar (MVar(..))
import GHC.Weak (Weak(..))
import qualified Control.Concurrent.MVar as Base

-- | Strict (WHNF) version of 'MVar'.
newtype MVar' a = MVar' (MVar a)
  deriving (MVar' a -> MVar' a -> Bool
(MVar' a -> MVar' a -> Bool)
-> (MVar' a -> MVar' a -> Bool) -> Eq (MVar' a)
forall a. MVar' a -> MVar' a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. MVar' a -> MVar' a -> Bool
== :: MVar' a -> MVar' a -> Bool
$c/= :: forall a. MVar' a -> MVar' a -> Bool
/= :: MVar' a -> MVar' a -> Bool
Eq, MVar' a -> ()
(MVar' a -> ()) -> NFData (MVar' a)
forall a. MVar' a -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall a. MVar' a -> ()
rnf :: MVar' a -> ()
NFData, (forall a. (a -> ()) -> MVar' a -> ()) -> NFData1 MVar'
forall a. (a -> ()) -> MVar' a -> ()
forall (f :: * -> *).
(forall a. (a -> ()) -> f a -> ()) -> NFData1 f
$cliftRnf :: forall a. (a -> ()) -> MVar' a -> ()
liftRnf :: forall a. (a -> ()) -> MVar' a -> ()
NFData1)

-- | 'Base.newEmptyMVar' for an 'MVar''.
newEmptyMVar' :: IO (MVar' a)
newEmptyMVar' :: forall a. IO (MVar' a)
newEmptyMVar' = MVar a -> MVar' a
forall a. MVar a -> MVar' a
MVar' (MVar a -> MVar' a) -> IO (MVar a) -> IO (MVar' a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (MVar a)
forall a. IO (MVar a)
Base.newEmptyMVar

-- | 'Base.newMVar' for an 'MVar''.
--
-- Evaluates the initial value to WHNF.
newMVar' :: a -> IO (MVar' a)
newMVar' :: forall a. a -> IO (MVar' a)
newMVar' a
a = (MVar a -> MVar' a) -> IO (MVar a) -> IO (MVar' a)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MVar a -> MVar' a
forall a. MVar a -> MVar' a
MVar' (IO (MVar a) -> IO (MVar' a))
-> (a -> IO (MVar a)) -> a -> IO (MVar' a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO (MVar a)
forall a. a -> IO (MVar a)
Base.newMVar (a -> IO (MVar' a)) -> IO a -> IO (MVar' a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> IO a
forall a. a -> IO a
evaluate a
a

-- | 'Base.takeMVar' for an 'MVar''.
takeMVar' :: MVar' a -> IO a
takeMVar' :: forall a. MVar' a -> IO a
takeMVar' (MVar' MVar a
var) = MVar a -> IO a
forall a. MVar a -> IO a
Base.takeMVar MVar a
var

-- | 'Base.putMVar' for an 'MVar''.
--
-- Evaluates the new value to WHNF.
putMVar' :: MVar' a -> a -> IO ()
putMVar' :: forall a. MVar' a -> a -> IO ()
putMVar' (MVar' MVar a
var) a
a = MVar a -> a -> IO ()
forall a. MVar a -> a -> IO ()
Base.putMVar MVar a
var (a -> IO ()) -> IO a -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> IO a
forall a. a -> IO a
evaluate a
a

-- | 'Base.readMVar' for an 'MVar''.
readMVar' :: MVar' a -> IO a
readMVar' :: forall a. MVar' a -> IO a
readMVar' (MVar' MVar a
var) = MVar a -> IO a
forall a. MVar a -> IO a
Base.readMVar MVar a
var

-- | 'Base.swapMVar' for an 'MVar''.
--
-- Evaluates the new value to WHNF.
swapMVar' :: MVar' a -> a -> IO a
swapMVar' :: forall a. MVar' a -> a -> IO a
swapMVar' (MVar' MVar a
var) a
a = MVar a -> a -> IO a
forall a. MVar a -> a -> IO a
Base.swapMVar MVar a
var (a -> IO a) -> IO a -> IO a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> IO a
forall a. a -> IO a
evaluate a
a

-- | 'Base.tryTakeMVar' for an 'MVar''.
tryTakeMVar' :: MVar' a -> IO (Maybe a)
tryTakeMVar' :: forall a. MVar' a -> IO (Maybe a)
tryTakeMVar' (MVar' MVar a
var) = MVar a -> IO (Maybe a)
forall a. MVar a -> IO (Maybe a)
Base.tryTakeMVar MVar a
var

-- | 'Base.tryPutMVar' for an 'MVar''.
--
-- Evaluates the new value to WHNF.
tryPutMVar' :: MVar' a -> a -> IO Bool
tryPutMVar' :: forall a. MVar' a -> a -> IO Bool
tryPutMVar' (MVar' MVar a
var) a
a = MVar a -> a -> IO Bool
forall a. MVar a -> a -> IO Bool
Base.tryPutMVar MVar a
var (a -> IO Bool) -> IO a -> IO Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> IO a
forall a. a -> IO a
evaluate a
a

-- | 'Base.tryReadMVar' for an 'MVar''.
tryReadMVar' :: MVar' a -> IO (Maybe a)
tryReadMVar' :: forall a. MVar' a -> IO (Maybe a)
tryReadMVar' (MVar' MVar a
var) = MVar a -> IO (Maybe a)
forall a. MVar a -> IO (Maybe a)
Base.tryReadMVar MVar a
var

-- | 'Base.isEmptyMVar' for an 'MVar''.
isEmptyMVar' :: MVar' a -> IO Bool
isEmptyMVar' :: forall a. MVar' a -> IO Bool
isEmptyMVar' (MVar' MVar a
var) = MVar a -> IO Bool
forall a. MVar a -> IO Bool
Base.isEmptyMVar MVar a
var

-- | 'Base.withMVar' for an 'MVar''.
withMVar' :: MVar' a -> (a -> IO b) -> IO b
withMVar' :: forall a b. MVar' a -> (a -> IO b) -> IO b
withMVar' (MVar' MVar a
var) a -> IO b
action = MVar a -> (a -> IO b) -> IO b
forall a b. MVar a -> (a -> IO b) -> IO b
Base.withMVar MVar a
var a -> IO b
action
{-# INLINE withMVar' #-}

-- | 'Base.withMVarMasked' for an 'MVar''.
withMVar'Masked :: MVar' a -> (a -> IO b) -> IO b
withMVar'Masked :: forall a b. MVar' a -> (a -> IO b) -> IO b
withMVar'Masked (MVar' MVar a
var) a -> IO b
action = MVar a -> (a -> IO b) -> IO b
forall a b. MVar a -> (a -> IO b) -> IO b
Base.withMVarMasked MVar a
var a -> IO b
action
{-# INLINE withMVar'Masked #-}

-- | 'Base.modifyMVar_' for an 'MVar''.
--
-- Evaluates the new value to WHNF.
modifyMVar'_ :: MVar' a -> (a -> IO a) -> IO ()
modifyMVar'_ :: forall a. MVar' a -> (a -> IO a) -> IO ()
modifyMVar'_ (MVar' MVar a
var) a -> IO a
action = MVar a -> (a -> IO a) -> IO ()
forall a. MVar a -> (a -> IO a) -> IO ()
Base.modifyMVar_ MVar a
var ((a -> IO a) -> IO ()) -> (a -> IO a) -> IO ()
forall a b. (a -> b) -> a -> b
$ \a
a0 -> do
  a
a <- a -> IO a
action a
a0
  a -> IO a
forall a. a -> IO a
evaluate a
a
{-# INLINE modifyMVar'_ #-}

-- | 'Base.modifyMVar' for an 'MVar''.
--
-- Evaluates the new value to WHNF.
modifyMVar' :: MVar' a -> (a -> IO (a, b)) -> IO b
modifyMVar' :: forall a b. MVar' a -> (a -> IO (a, b)) -> IO b
modifyMVar' (MVar' MVar a
var) a -> IO (a, b)
action = MVar a -> (a -> IO (a, b)) -> IO b
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
Base.modifyMVar MVar a
var ((a -> IO (a, b)) -> IO b) -> (a -> IO (a, b)) -> IO b
forall a b. (a -> b) -> a -> b
$ \a
a0 -> do
  (a
a, b
b) <- a -> IO (a, b)
action a
a0
  (, b
b) (a -> (a, b)) -> IO a -> IO (a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> IO a
forall a. a -> IO a
evaluate a
a
{-# INLINE modifyMVar' #-}

-- | 'Base.modifyMVarMasked_' for an 'MVar''.
--
-- Evaluates the new value to WHNF.
modifyMVar'Masked_ :: MVar' a -> (a -> IO a) -> IO ()
modifyMVar'Masked_ :: forall a. MVar' a -> (a -> IO a) -> IO ()
modifyMVar'Masked_ (MVar' MVar a
var) a -> IO a
action = MVar a -> (a -> IO a) -> IO ()
forall a. MVar a -> (a -> IO a) -> IO ()
Base.modifyMVarMasked_ MVar a
var ((a -> IO a) -> IO ()) -> (a -> IO a) -> IO ()
forall a b. (a -> b) -> a -> b
$ \a
a0 -> do
  a
a <- a -> IO a
action a
a0
  a -> IO a
forall a. a -> IO a
evaluate a
a
{-# INLINE modifyMVar'Masked_ #-}

-- | 'Base.modifyMVarMasked' for an 'MVar''.
--
-- Evaluates the new value to WHNF.
modifyMVar'Masked :: MVar' a -> (a -> IO (a, b)) -> IO b
modifyMVar'Masked :: forall a b. MVar' a -> (a -> IO (a, b)) -> IO b
modifyMVar'Masked (MVar' MVar a
var) a -> IO (a, b)
action = MVar a -> (a -> IO (a, b)) -> IO b
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
Base.modifyMVarMasked MVar a
var ((a -> IO (a, b)) -> IO b) -> (a -> IO (a, b)) -> IO b
forall a b. (a -> b) -> a -> b
$ \a
a0 -> do
  (a
a, b
b) <- a -> IO (a, b)
action a
a0
  (, b
b) (a -> (a, b)) -> IO a -> IO (a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> IO a
forall a. a -> IO a
evaluate a
a
{-# INLINE modifyMVar'Masked #-}

-- | 'Base.mkWeakMVar' for an 'MVar''.
mkWeakMVar' :: MVar' a -> IO () -> IO (Weak (MVar' a))
mkWeakMVar' :: forall a. MVar' a -> IO () -> IO (Weak (MVar' a))
mkWeakMVar' var :: MVar' a
var@(MVar' (MVar MVar# RealWorld a
var#)) (IO State# RealWorld -> (# State# RealWorld, () #)
finalizer) = (State# RealWorld -> (# State# RealWorld, Weak (MVar' a) #))
-> IO (Weak (MVar' a))
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, Weak (MVar' a) #))
 -> IO (Weak (MVar' a)))
-> (State# RealWorld -> (# State# RealWorld, Weak (MVar' a) #))
-> IO (Weak (MVar' a))
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s0 ->
  case MVar# RealWorld a
-> MVar' a
-> (State# RealWorld -> (# State# RealWorld, () #))
-> State# RealWorld
-> (# State# RealWorld, Weak# (MVar' a) #)
forall a b c.
a
-> b
-> (State# RealWorld -> (# State# RealWorld, c #))
-> State# RealWorld
-> (# State# RealWorld, Weak# b #)
mkWeak# MVar# RealWorld a
var# MVar' a
var State# RealWorld -> (# State# RealWorld, () #)
finalizer State# RealWorld
s0 of
    (# State# RealWorld
s1, Weak# (MVar' a)
w #) -> (# State# RealWorld
s1, Weak# (MVar' a) -> Weak (MVar' a)
forall v. Weak# v -> Weak v
Weak Weak# (MVar' a)
w #)