module Hans.Timers (
Milliseconds
, Timer()
, delay
, delay_
, cancel
, expired
) where
import Control.Concurrent (forkIO,ThreadId,threadDelay,killThread
,mkWeakThreadId)
import GHC.Conc (threadStatus,ThreadStatus(..))
import System.Mem.Weak (Weak,deRefWeak)
type Milliseconds = Int
newtype Timer = Timer (Weak ThreadId)
delay :: Milliseconds -> IO () -> IO Timer
delay n body =
do tid <- forkIO (threadDelay (n * 1000) >> body)
wid <- mkWeakThreadId tid
return (Timer wid)
delay_ :: Milliseconds -> IO () -> IO ()
delay_ n body =
do _ <- forkIO (threadDelay (n * 1000) >> body)
return ()
cancel :: Timer -> IO ()
cancel (Timer wid) =
do mb <- deRefWeak wid
case mb of
Just tid -> killThread tid
Nothing -> return ()
expired :: Timer -> IO Bool
expired (Timer wid) =
do mb <- deRefWeak wid
case mb of
Just tid -> do status <- threadStatus tid
case status of
ThreadRunning -> return False
ThreadBlocked _ -> return False
_ -> return True
Nothing -> return True