module System.SimpleTimeout.Limits
( TimeLimit
, SizeLimit
, Budget
, newBudget
, checkBudget
, decSizeBudget
) where
import System.SimpleTimeout (TimeoutHandle, timeoutHandle, timeout)
import Control.Concurrent.MVar (MVar, newMVar, modifyMVar)
type TimeLimit = Double
type SizeLimit = Int
data Budget
= Budget TimeoutHandle (MVar SizeLimit)
newBudget :: TimeLimit -> SizeLimit -> IO Budget
newBudget t s = do
th <- timeoutHandle t
mv <- newMVar s
return $ Budget th mv
checkBudget
:: Budget
-> Int
-> (Double -> IO a)
-> IO a
-> IO a
-> IO a
checkBudget (Budget tb sb) dec ta sa na = do
r <- modifyMVar sb $ \a -> return $
if a > 0 then (adec, True) else (a, False)
if r then timeout tb ta na else sa
decSizeBudget
:: Budget
-> (SizeLimit -> (SizeLimit, a))
-> IO a
decSizeBudget (Budget _ sb) f
= modifyMVar sb $ return . f