module Dingo.Internal.Queue ( readChanTimeout ) where import Control.Concurrent (forkIO, threadDelay, killThread, myThreadId) import Control.Concurrent.Chan.Strict (Chan, readChan) import Control.Concurrent.MVar.Strict (newEmptyMVar, putMVar, takeMVar) import Control.DeepSeq (NFData) -- Read a Chan with timeout. readChanTimeout :: NFData a => Chan a -> Int -> IO (Maybe a) readChanTimeout ch timeout = do result <- newEmptyMVar _ <- forkIO $ do wid <- myThreadId readerThreadId <- forkIO $ do x <- readChan ch killThread wid putMVar result (Just x) threadDelay timeout killThread readerThreadId putMVar result Nothing -- Block waiting for either timeout or the read. takeMVar result