{-# LANGUAGE CPP #-} module Network.Wai.Handler.Warp.Counter ( Counter , newCounter , waitForZero , increase , decrease ) where import Control.Concurrent.STM import Network.Wai.Handler.Warp.Imports newtype Counter = Counter (TVar Int) newCounter :: IO Counter newCounter :: IO Counter newCounter = TVar Int -> Counter Counter forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall a. a -> IO (TVar a) newTVarIO Int 0 waitForZero :: Counter -> IO () waitForZero :: Counter -> IO () waitForZero (Counter TVar Int ref) = forall a. STM a -> IO a atomically forall a b. (a -> b) -> a -> b $ do Int x <- forall a. TVar a -> STM a readTVar TVar Int ref forall (f :: * -> *). Applicative f => Bool -> f () -> f () unless (Int x forall a. Eq a => a -> a -> Bool == Int 0) forall a. STM a retry increase :: Counter -> IO () increase :: Counter -> IO () increase (Counter TVar Int ref) = forall a. STM a -> IO a atomically forall a b. (a -> b) -> a -> b $ forall a. TVar a -> (a -> a) -> STM () modifyTVar' TVar Int ref forall a b. (a -> b) -> a -> b $ \Int x -> Int x forall a. Num a => a -> a -> a + Int 1 decrease :: Counter -> IO () decrease :: Counter -> IO () decrease (Counter TVar Int ref) = forall a. STM a -> IO a atomically forall a b. (a -> b) -> a -> b $ forall a. TVar a -> (a -> a) -> STM () modifyTVar' TVar Int ref forall a b. (a -> b) -> a -> b $ \Int x -> Int x forall a. Num a => a -> a -> a - Int 1