    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE CPP          #-}

    module Snap.Internal.Http.Server.Common
      ( atomicModifyIORef'
      , eatException
      ) where

    import           Control.Exception (SomeException, catch)
    import           Control.Monad     (void)
    import           Prelude           (IO, return, ($!))

    #if MIN_VERSION_base(4,6,0)
    ------------------------------------------------------------------------------
    import           Data.IORef        (atomicModifyIORef')

    #else
    ------------------------------------------------------------------------------
    import           Data.IORef        (IORef, atomicModifyIORef)
    import           Prelude           (seq)

    ------------------------------------------------------------------------------
    -- | Strict version of 'atomicModifyIORef'.  This forces both the value stored
    -- in the 'IORef' as well as the value returned.
    atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b
    atomicModifyIORef' ref f = do
        b <- atomicModifyIORef ref
                (\x -> let (a, b) = f x
                        in (a, a `seq` b))
        b `seq` return b
    #endif

    ------------------------------------------------------------------------------
    eatException :: IO a -> IO ()
    eatException :: forall a. IO a -> IO ()
    eatException IO a
    m = IO a -> IO ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void IO a
    m IO () -> (SomeException -> IO ()) -> IO ()
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    `catch` SomeException -> IO ()
    f
      where
        f :: SomeException -> IO ()
        f :: SomeException -> IO ()
    f !SomeException
    _ = () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (() -> IO ()) -> () -> IO ()
    forall a b. (a -> b) -> a -> b
    $! ()