module Main where
import Control.Concurrent
import Control.Concurrent.STM
import Data.Time.Clock.POSIX
import Control.Event.Timeout
import Text.Printf (printf)
singleTimeout secs = do
a <- atomically $ newTVar 0
startTime <- getPOSIXTime
addTimeout secs (getPOSIXTime >>= atomically . writeTVar a)
endTime <- atomically (do
t <- readTVar a
if t == 0
then retry
else return t)
printf "%dms sleep took: %s\n" ((truncate $ secs * 1000) :: Int) (show (endTime - startTime))
multiTimeout :: Int -> Float -> IO ()
multiTimeout n secs = do
a <- atomically $ newTVar n
startTime <- getPOSIXTime
mapM_ (const $ addTimeout secs (atomically $ readTVar a >>= writeTVar a . ((flip (-)) 1))) [1..n]
atomically (do
n' <- readTVar a
if n' == 0
then return ()
else retry)
endTime <- getPOSIXTime
printf "%d timeouts for %d ms took %s\n" n ((truncate $ secs * 1000) :: Int) (show $ endTime - startTime)
setAndCancelTimeout :: Int -> Float -> IO ()
setAndCancelTimeout n secs = do
a <- atomically $ newTVar (0 :: Int)
startTime <- getPOSIXTime
tags <- mapM (const $ addTimeout secs (atomically $ readTVar a >>= writeTVar a . ((+) 1))) [1..n]
mapM (atomically . cancelTimeout) tags
endTime <- getPOSIXTime
expired <- atomically $ readTVar a
printf "Setting and killing %d timeouts for %d ms took %s and %d expired\n" n ((truncate $ secs * 1000) :: Int) (show $ endTime - startTime) expired
main = do
sequence [singleTimeout 0, singleTimeout 0.1, singleTimeout 0.5, singleTimeout 1.0]
sequence [multiTimeout 10 0.1, multiTimeout 100 0.1, multiTimeout 1000 0.1, multiTimeout 10000 0.1, multiTimeout 100000 0.1]
sequence [setAndCancelTimeout 10 0.1, setAndCancelTimeout 100 0.1, setAndCancelTimeout 1000 0.1, setAndCancelTimeout 10000 0.1, setAndCancelTimeout 100000 0.1]
return ()