X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FResponseWriter.hs;h=9751a7699c7b175ba062ae750d4c5f710fffeac0;hb=0ff0346;hp=63174b7cb5ea3d8f727c860d77efdea0710134dd;hpb=73b5fba4907604681d778d3bd54cd65fd84b4454;p=Lucu.git diff --git a/Network/HTTP/Lucu/ResponseWriter.hs b/Network/HTTP/Lucu/ResponseWriter.hs index 63174b7..9751a76 100644 --- a/Network/HTTP/Lucu/ResponseWriter.hs +++ b/Network/HTTP/Lucu/ResponseWriter.hs @@ -1,3 +1,7 @@ +{-# LANGUAGE + BangPatterns + , UnicodeSyntax + #-} module Network.HTTP.Lucu.ResponseWriter ( responseWriter ) @@ -28,37 +32,35 @@ responseWriter !cnf !h !tQueue !readerTID `catches` [ Handler (( \ _ -> return () ) :: IOException -> IO ()) , Handler ( \ ThreadKilled -> return () ) - , Handler ( \ BlockedIndefinitely -> hPutStrLn stderr "requestWriter: blocked indefinitely" ) + , Handler ( \ BlockedIndefinitelyOnSTM -> hPutStrLn stderr "requestWriter: blocked indefinitely" ) , Handler (( \ e -> hPutStrLn stderr (show e) ) :: SomeException -> IO ()) ] where awaitSomethingToWrite :: IO () awaitSomethingToWrite = {-# SCC "awaitSomethingToWrite" #-} - do action - <- atomically $! - -- キューが空でなくなるまで待つ - do queue <- readTVar tQueue - -- GettingBody 状態にあり、Continue が期待され - -- てゐて、それがまだ送信前なのであれば、 - -- Continue を送信する。 - case S.viewr queue of - EmptyR -> retry - _ :> itr -> do state <- readItr itr itrState id + join $! + atomically $! + -- キューが空でなくなるまで待つ + do queue <- readTVar tQueue + -- GettingBody 状態にあり、Continue が期待されてゐ + -- て、それがまだ送信前なのであれば、Continue を送 + -- 信する。 + case S.viewr queue of + EmptyR -> retry + _ :> itr -> do state <- readItr itr itrState id - if state == GettingBody then - writeContinueIfNecessary itr - else - if state >= DecidingBody then - writeHeaderOrBodyIfNecessary itr - else - retry - action + if state == GettingBody then + writeContinueIfNecessary itr + else + if state >= DecidingBody then + writeHeaderOrBodyIfNecessary itr + else + retry writeContinueIfNecessary :: Interaction -> STM (IO ()) - writeContinueIfNecessary itr + writeContinueIfNecessary !itr = {-# SCC "writeContinueIfNecessary" #-} - itr `seq` do expectedContinue <- readItr itr itrExpectedContinue id if expectedContinue then do wroteContinue <- readItr itr itrWroteContinue id @@ -75,13 +77,12 @@ responseWriter !cnf !h !tQueue !readerTID retry writeHeaderOrBodyIfNecessary :: Interaction -> STM (IO ()) - writeHeaderOrBodyIfNecessary itr + writeHeaderOrBodyIfNecessary !itr -- DecidingBody 以降の状態にあり、まだヘッダを出力する前であ -- れば、ヘッダを出力する。ヘッダ出力後であり、bodyToSend が -- 空でなければ、それを出力する。空である時は、もし状態が -- Done であれば後処理をする。 = {-# SCC "writeHeaderOrBodyIfNecessary" #-} - itr `seq` do wroteHeader <- readItr itr itrWroteHeader id if not wroteHeader then @@ -100,9 +101,8 @@ responseWriter !cnf !h !tQueue !readerTID return $! writeBodyChunk itr writeContinue :: Interaction -> IO () - writeContinue itr + writeContinue !itr = {-# SCC "writeContinue" #-} - itr `seq` do let cont = Response { resVersion = HttpVersion 1 1 , resStatus = Continue @@ -115,9 +115,8 @@ responseWriter !cnf !h !tQueue !readerTID awaitSomethingToWrite writeHeader :: Interaction -> IO () - writeHeader itr + writeHeader !itr = {-# SCC "writeHeader" #-} - itr `seq` do res <- atomically $! do writeItr itr itrWroteHeader True readItr itr itrResponse id hPutResponse h res @@ -125,9 +124,8 @@ responseWriter !cnf !h !tQueue !readerTID awaitSomethingToWrite writeBodyChunk :: Interaction -> IO () - writeBodyChunk itr + writeBodyChunk !itr = {-# SCC "writeBodyChunk" #-} - itr `seq` do willDiscardBody <- atomically $! readItr itr itrWillDiscardBody id willChunkBody <- atomically $! readItr itr itrWillChunkBody id chunk <- atomically $! do chunk <- readItr itr itrBodyToSend id @@ -145,18 +143,16 @@ responseWriter !cnf !h !tQueue !readerTID awaitSomethingToWrite finishBodyChunk :: Interaction -> IO () - finishBodyChunk itr + finishBodyChunk !itr = {-# SCC "finishBodyChunk" #-} - itr `seq` do willDiscardBody <- atomically $! readItr itr itrWillDiscardBody id willChunkBody <- atomically $! readItr itr itrWillChunkBody id when (not willDiscardBody && willChunkBody) $ hPutLBS h (C8.pack "0\r\n\r\n") >> hFlush h finalize :: Interaction -> IO () - finalize itr + finalize !itr = {-# SCC "finalize" #-} - itr `seq` do finishBodyChunk itr willClose <- atomically $! do queue <- readTVar tQueue