@@ -0,0 +1,58 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+module Network.Wai.Application.Devel
14+import Control.Concurrent (forkIO)
15+import Control.Concurrent.MVar
16+ ( MVar, newEmptyMVar, newMVar
17+ , takeMVar, putMVar, readMVar
19+import Network.Wai (Application, responseLBS, status500)
20+import Data.ByteString.Lazy.Char8 ()
21+import Control.Monad.IO.Class (liftIO)
23+type AppHolder = MVar (Application, MVar ())
24+type AppRunner = Application -> IO ()
25+type WithAppRunner = AppRunner -> IO ()
27+initAppHolder :: IO AppHolder
30+ newMVar (initApp, flag)
33+ $ responseLBS status500 [("Content-Type", "text/plain")]
34+ $ "No app has yet been loaded"
36+swapAppSimple :: Application -> AppHolder -> IO ()
42+swapApp :: WithAppRunner -> AppHolder -> IO ()
43+swapApp war ah = void $ forkIO $ war $ \app -> do
44+ (_, oldFlag) <- takeMVar ah
45+ -- allow the old app to cleanup
47+ -- now place the new app into the AppHolder, waiting for a termination
50+ putMVar ah (app, flag)
51+ takeMVar flag -- this causes execution to hang until we are terminated
53+ void x = x >> return ()
55+toApp :: AppHolder -> Application
57+ (app, _) <- liftIO $ readMVar ah