module Control.Concurrent.Throttled
( Throttle
, newThrottle
, throttled
) where
import Control.Monad
import Control.Exception
import Control.Concurrent
newtype Throttle
= Throttle (MVar (MVar ()))
newThrottle :: Int -> IO Throttle
newThrottle maxConcurrent = do
mv <- newEmptyMVar
forM_ [1..maxConcurrent] $ \_ -> forkIO . forever $ do
m <- takeMVar mv
putMVar m ()
putMVar m ()
return $ Throttle mv
throttled :: Throttle -> IO a -> IO a
throttled (Throttle mv) act = do
m <- newEmptyMVar
putMVar mv m
readMVar m
act `finally` takeMVar m