    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
      ref <- Bool -> IO (IORef Bool)
    forall a. a -> IO (IORef a)
    newIORef Bool
    False
      bracket (async $ worker delay ref) cancel $ \Async ()
    _ -> do
        IO Bool -> IO a
    action (IO Bool -> IO a) -> IO Bool -> IO a
    forall a b. (a -> b) -> a -> b
    $ IORef Bool -> (Bool -> (Bool, Bool)) -> IO Bool
    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
      IO () -> IO ()
    forall (f :: * -> *) a b. Applicative f => f a -> f b
    forever (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ do
        Seconds -> IO ()
    sleep Seconds
    delay
        IORef Bool -> Bool -> IO ()
    forall a. IORef a -> a -> IO ()
    atomicWriteIORef IORef Bool
    ref Bool
    True