@@ -36,29 +36,26 @@ run :: Port -> ModuleName -> FunctionName -> IO ()
36run port modu func = do
36run port modu func = do
37 queue <- C.newChan
37 queue <- C.newChan
38 mqueue <- M.newMVar queue
38 mqueue <- M.newMVar queue
39− mmqueue <- M.newMVar mqueue
40− startApp mqueue $ loadingApp Nothing
39+ startApp queue $ loadingApp Nothing
41− _ <- forkIO $ fillApp modu func mmqueue
40+ _ <- forkIO $ fillApp modu func mqueue
42− run' port queue
41+ run' port mqueue
44−startApp :: M.MVar Queue -> Handler -> IO ()
43+startApp :: Queue -> Handler -> IO ()
45−startApp mqueue withApp =
44+startApp queue withApp = do
46 forkIO (withApp go) >> return ()
45 forkIO (withApp go) >> return ()
48 go app = do
47 go app = do
49− queue' <- M.tryTakeMVar mqueue
48+ msession <- C.readChan queue
50− case queue' of
49+ case msession of
51 Nothing -> return ()
50 Nothing -> return ()
53− M.putMVar mqueue queue
54− (req, onRes) <- C.readChan queue
51+ Just (req, onRes) -> do
55 res <- app req
52 res <- app req
56 -- FIXME exceptions?
53 -- FIXME exceptions?
60−fillApp :: String -> String -> M.MVar (M.MVar Queue) -> IO ()
57+fillApp :: String -> String -> M.MVar Queue -> IO ()
61−fillApp modu func mmqueue =
58+fillApp modu func mqueue =
62 go Nothing []
59 go Nothing []
64 go prevError prevFiles = do
61 go prevError prevFiles = do
@@ -76,35 +73,35 @@ fillApp modu func mmqueue =
76 go newError newFiles
73 go newError newFiles
77 reload prevError = do
74 reload prevError = do
78 putStrLn "Attempting to interpret your app..."
75 putStrLn "Attempting to interpret your app..."
79− loadingApp' prevError mmqueue
76+ loadingApp' prevError mqueue
80 res <- theapp modu func
77 res <- theapp modu func
81 case res of
78 case res of
82 Left err -> do
79 Left err -> do
83 putStrLn $ "Compile failed: " ++ show err
80 putStrLn $ "Compile failed: " ++ show err
84− loadingApp' (Just $ toException err) mmqueue
81+ loadingApp' (Just $ toException err) mqueue
85 return (Just $ toException err, [])
82 return (Just $ toException err, [])
86 Right (app, files) -> do
83 Right (app, files) -> do
87 putStrLn "Interpreting success, new app loaded"
84 putStrLn "Interpreting success, new app loaded"
88 handle onInitErr $ do
85 handle onInitErr $ do
89− swapApp app mmqueue
86+ swapApp app mqueue
90 files' <- forM files $ \f -> do
87 files' <- forM files $ \f -> do
91 t <- getModificationTime f
88 t <- getModificationTime f
92 return (f, t)
89 return (f, t)
93 return (Nothing, files')
90 return (Nothing, files')
94 onInitErr e = do
91 onInitErr e = do
95 putStrLn $ "Error initializing application: " ++ show e
92 putStrLn $ "Error initializing application: " ++ show e
96− loadingApp' (Just e) mmqueue
93+ loadingApp' (Just e) mqueue
97 return (Just e, [])
94 return (Just e, [])
99−loadingApp' :: Maybe SomeException -> M.MVar (M.MVar Queue) -> IO ()
96+loadingApp' :: Maybe SomeException -> M.MVar Queue -> IO ()
100−loadingApp' err mmqueue = swapApp (loadingApp err) mmqueue
97+loadingApp' err mqueue = swapApp (loadingApp err) mqueue
102−swapApp app mmqueue = do
99+swapApp app mqueue = do
103− oldmqueue <- M.takeMVar mmqueue
100+ oldqueue <- M.takeMVar mqueue
104− queue <- M.takeMVar oldmqueue
101+ C.writeChan oldqueue Nothing
105− mqueue <- M.newMVar queue
102+ queue <- C.newChan
106− M.putMVar mmqueue mqueue
103+ M.putMVar mqueue queue
107− startApp mqueue app
104+ startApp queue app
109loadingApp :: Maybe SomeException -> Handler
106loadingApp :: Maybe SomeException -> Handler
110loadingApp err f =
107loadingApp err f =
@@ -132,7 +129,7 @@ theapp modu func =
132 toSlash '.' = '/'
129 toSlash '.' = '/'
133 toSlash c = c
130 toSlash c = c
135−run' :: Port -> Queue -> IO ()
132+run' :: Port -> M.MVar Queue -> IO ()
136run' port = withSocketsDo .
133run' port = withSocketsDo .
138 (listenOn $ PortNumber $ fromIntegral port)
135 (listenOn $ PortNumber $ fromIntegral port)
@@ -140,22 +137,23 @@ run' port = withSocketsDo .
140 serveConnections port
137 serveConnections port
141type Port = Int
138type Port = Int
143−serveConnections :: Port -> Queue -> Socket -> IO ()
140+serveConnections :: Port -> M.MVar Queue -> Socket -> IO ()
144−serveConnections port queue socket = do
141+serveConnections port mqueue socket = do
145 (conn, remoteHost', _) <- accept socket
142 (conn, remoteHost', _) <- accept socket
146− _ <- forkIO $ serveConnection port queue conn remoteHost'
143+ _ <- forkIO $ serveConnection port mqueue conn remoteHost'
147− serveConnections port queue socket
144+ serveConnections port mqueue socket
149−type Queue = C.Chan (Request, Response -> IO ())
146+type Queue = C.Chan (Maybe (Request, Response -> IO ()))
151−serveConnection :: Port -> Queue -> Handle -> String -> IO ()
148+serveConnection :: Port -> M.MVar Queue -> Handle -> String -> IO ()
152−serveConnection port queue conn remoteHost' = do
149+serveConnection port mqueue conn remoteHost' = do
153 env <- hParseRequest port conn remoteHost'
150 env <- hParseRequest port conn remoteHost'
154 let onRes res =
151 let onRes res =
156 (sendResponse (httpVersion env) conn res)
153 (sendResponse (httpVersion env) conn res)
157 (hClose conn)
154 (hClose conn)
155+ queue <- M.readMVar mqueue
158− C.writeChan queue (env, onRes)
156+ C.writeChan queue $ Just (env, onRes)
160hParseRequest :: Port -> Handle -> String -> IO Request
158hParseRequest :: Port -> Handle -> String -> IO Request
161hParseRequest port conn remoteHost' = do
159hParseRequest port conn remoteHost' = do