module Test.Hspec.Core.Timer (withTimer) where import Prelude () import Test.Hspec.Core.Compat import Control.Concurrent.Async import Test.Hspec.Core.Clock withTimer :: Seconds -> (IO Bool -> IO a) -> IO a withTimer :: forall a. Seconds -> (IO Bool -> IO a) -> IO a withTimer Seconds delay IO Bool -> IO a action = do IORef Bool ref <- forall a. a -> IO (IORef a) newIORef Bool False forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c bracket (forall a. IO a -> IO (Async a) async forall a b. (a -> b) -> a -> b $ Seconds -> IORef Bool -> IO () worker Seconds delay IORef Bool ref) forall a. Async a -> IO () cancel forall a b. (a -> b) -> a -> b $ \Async () _ -> do IO Bool -> IO a action forall a b. (a -> b) -> a -> b $ forall a b. IORef a -> (a -> (a, b)) -> IO b atomicModifyIORef IORef Bool ref (\Bool a -> (Bool False, Bool a)) worker :: Seconds -> IORef Bool -> IO () worker :: Seconds -> IORef Bool -> IO () worker Seconds delay IORef Bool ref = do forall (f :: * -> *) a b. Applicative f => f a -> f b forever forall a b. (a -> b) -> a -> b $ do Seconds -> IO () sleep Seconds delay forall a. IORef a -> a -> IO () atomicWriteIORef IORef Bool ref Bool True