mighttpd2-2.8.5: src/State.hs
module State (
Status(..)
, Stater
, initStater
, getConnectionCounter
, increment
, decrement
, isRetiring
, goRetiring
, getServerStatus
, setMyWarpThreadId
, addAnotherWarpThreadId
, ifWarpThreadsAreActive
) where
import Control.Applicative
import Control.Concurrent
import Data.IORef
import Utils
----------------------------------------------------------------
data Status = Serving | Retiring deriving (Eq, Show)
data Two a = Zero | One a | Two a a
data State = State {
connectionCounter :: !Int
, serverStatus :: !Status
, warpThreadId :: !(Two ThreadId)
}
initialState :: State
initialState = State 0 Serving Zero
----------------------------------------------------------------
newtype Stater = Stater (IORef State)
initStater :: IO Stater
initStater = Stater <$> newIORef initialState
----------------------------------------------------------------
getConnectionCounter :: Stater -> IO Int
getConnectionCounter (Stater sref) = connectionCounter <$> readIORef sref
increment :: Stater -> IO ()
increment (Stater sref) =
strictAtomicModifyIORef sref $ \st -> st {
connectionCounter = connectionCounter st + 1
}
decrement :: Stater -> IO ()
decrement (Stater sref) =
strictAtomicModifyIORef sref $ \st -> st {
connectionCounter = connectionCounter st - 1
}
----------------------------------------------------------------
getServerStatus :: Stater -> IO Status
getServerStatus (Stater sref) = serverStatus <$> readIORef sref
isRetiring :: Stater -> IO Bool
isRetiring stt = (== Retiring) <$> getServerStatus stt
goRetiring :: Stater -> IO ()
goRetiring (Stater sref) =
strictAtomicModifyIORef sref $ \st -> st {
serverStatus = Retiring
, warpThreadId = Zero
}
----------------------------------------------------------------
getWarpThreadId :: Stater -> IO (Two ThreadId)
getWarpThreadId (Stater sref) = warpThreadId <$> readIORef sref
setWarpThreadId :: Stater -> Two ThreadId -> IO ()
setWarpThreadId (Stater sref) ttids =
strictAtomicModifyIORef sref $ \st -> st {
warpThreadId = ttids
}
setMyWarpThreadId :: Stater -> IO ()
setMyWarpThreadId stt = do
myid <- myThreadId
setWarpThreadId stt (One myid)
addAnotherWarpThreadId :: Stater -> ThreadId -> IO ()
addAnotherWarpThreadId stt aid = do
ttids <- getWarpThreadId stt
case ttids of
One tid -> setWarpThreadId stt (Two tid aid)
_ -> undefined -- FIXME
ifWarpThreadsAreActive :: Stater -> IO () -> IO ()
ifWarpThreadsAreActive stt act = do
ttids <- getWarpThreadId stt
case ttids of
Zero -> return ()
One tid -> do
killThread tid
act
Two tid1 tid2 -> do
killThread tid1
killThread tid2
act