-- Most important is to not export the data constructor from this module
-- and to not expose 'writeShuttingDown' to the end user.
module Network.Wai.Handler.Warp.ShuttingDown (
    ShuttingDown,
    newShuttingDown,
    readShuttingDown,
    readShuttingDownSTM,
    writeShuttingDown,
) where

import Control.Concurrent.STM (
    STM,
    TVar,
    atomically,
    newTVarIO,
    readTVar,
    readTVarIO,
    writeTVar,
 )

newtype ShuttingDown = ShuttingDown (TVar Bool)

newShuttingDown :: IO ShuttingDown
newShuttingDown :: IO ShuttingDown
newShuttingDown = TVar Bool -> ShuttingDown
ShuttingDown (TVar Bool -> ShuttingDown) -> IO (TVar Bool) -> IO ShuttingDown
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> IO (TVar Bool)
forall a. a -> IO (TVar a)
newTVarIO Bool
False

readShuttingDown :: ShuttingDown -> IO Bool
readShuttingDown :: ShuttingDown -> IO Bool
readShuttingDown (ShuttingDown TVar Bool
var) = TVar Bool -> IO Bool
forall a. TVar a -> IO a
readTVarIO TVar Bool
var

readShuttingDownSTM :: ShuttingDown -> STM Bool
readShuttingDownSTM :: ShuttingDown -> STM Bool
readShuttingDownSTM (ShuttingDown TVar Bool
var) = TVar Bool -> STM Bool
forall a. TVar a -> STM a
readTVar TVar Bool
var

writeShuttingDown :: ShuttingDown -> Bool -> IO ()
writeShuttingDown :: ShuttingDown -> Bool -> IO ()
writeShuttingDown (ShuttingDown TVar Bool
var) Bool
b =
    STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TVar Bool -> Bool -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar Bool
var Bool
b