module Control.Concurrent.STM.SSem(SSem, new, wait, signal, tryWait
, waitN, signalN, tryWaitN
, getValue) where
import Control.Monad.STM(STM,retry)
import Control.Concurrent.STM.TVar(newTVar,readTVar,writeTVar)
import Control.Concurrent.STM.SSemInternals(SSem(SSem))
new :: Int -> STM SSem
new :: Int -> STM SSem
new = (TVar Int -> SSem) -> STM (TVar Int) -> STM SSem
forall a b. (a -> b) -> STM a -> STM b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TVar Int -> SSem
SSem (STM (TVar Int) -> STM SSem)
-> (Int -> STM (TVar Int)) -> Int -> STM SSem
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> STM (TVar Int)
forall a. a -> STM (TVar a)
newTVar
wait :: SSem -> STM ()
wait :: SSem -> STM ()
wait = (SSem -> Int -> STM ()) -> Int -> SSem -> STM ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip SSem -> Int -> STM ()
waitN Int
1
waitN :: SSem -> Int -> STM ()
waitN :: SSem -> Int -> STM ()
waitN (SSem TVar Int
s) Int
i = do
Int
v <- TVar Int -> STM Int
forall a. TVar a -> STM a
readTVar TVar Int
s
if Int
v Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
i
then TVar Int -> Int -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar Int
s (Int -> STM ()) -> Int -> STM ()
forall a b. (a -> b) -> a -> b
$! Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i
else STM ()
forall a. STM a
retry
signal :: SSem -> STM ()
signal :: SSem -> STM ()
signal = (SSem -> Int -> STM ()) -> Int -> SSem -> STM ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip SSem -> Int -> STM ()
signalN Int
1
signalN :: SSem -> Int -> STM ()
signalN :: SSem -> Int -> STM ()
signalN (SSem TVar Int
s) Int
i = do
Int
v <- TVar Int -> STM Int
forall a. TVar a -> STM a
readTVar TVar Int
s
TVar Int -> Int -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar Int
s (Int -> STM ()) -> Int -> STM ()
forall a b. (a -> b) -> a -> b
$! Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i
tryWait :: SSem -> STM (Maybe Int)
tryWait :: SSem -> STM (Maybe Int)
tryWait = (SSem -> Int -> STM (Maybe Int)) -> Int -> SSem -> STM (Maybe Int)
forall a b c. (a -> b -> c) -> b -> a -> c
flip SSem -> Int -> STM (Maybe Int)
tryWaitN Int
1
tryWaitN :: SSem -> Int -> STM (Maybe Int)
tryWaitN :: SSem -> Int -> STM (Maybe Int)
tryWaitN (SSem TVar Int
s) Int
i = do
Int
v <- TVar Int -> STM Int
forall a. TVar a -> STM a
readTVar TVar Int
s
if Int
v Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
i
then do TVar Int -> Int -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar Int
s (Int -> STM ()) -> Int -> STM ()
forall a b. (a -> b) -> a -> b
$! Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i
Maybe Int -> STM (Maybe Int)
forall a. a -> STM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i)
else Maybe Int -> STM (Maybe Int)
forall a. a -> STM a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int
forall a. Maybe a
Nothing
getValue :: SSem -> STM Int
getValue :: SSem -> STM Int
getValue (SSem TVar Int
s) = TVar Int -> STM Int
forall a. TVar a -> STM a
readTVar TVar Int
s