@@ -358,16 +358,20 @@ parseRequest' conn port (firstLine:otherLines) remoteHost' src = do
358358 -- We can't use the standard isolate, as its counter is not
359359 -- kept in a mutable variable.
360360 lenRef <- liftIO $ I.newIORef len0
361− let isolate = C.Conduit push close
362− push bs = do
361+ let isolate = C.Running push C.Closed
362+ push bs = flip C.ConduitM (return ()) $ do
363363 len <- liftIO $ I.readIORef lenRef
364364 let (a, b) = S.splitAt len bs
365365 len' = len - S.length a
366366 liftIO $ I.writeIORef lenRef len'
367367 return $ if len' == 0
368− then C.Finished (if S.null b then Nothing else Just b) (if S.null a then [] else [a])
369− else C.Producing isolate [a]
370− close = return []
368+ then
369+ let mleftover = if S.null b then Nothing else Just b
370+ final = C.Finished mleftover
371+ in if S.null a
372+ then final
373+ else C.HaveMore final (return ()) a
374+ else C.HaveMore isolate (return ()) a
371375
372376 -- Make sure that we don't connect to the source after the
373377 -- isolate conduit closes.
@@ -393,14 +397,13 @@ parseRequest' conn port (firstLine:otherLines) remoteHost' src = do
393397 -- as we'd now have to check the BufferedSource status on
394398 -- each call. Worth looking into.
395399
396− wrap src' = C.Source
397− { C.sourcePull = do
400+ wrap src' = C.SourceM
401+ (do
398402 len <- liftIO $ I.readIORef lenRef
399403 if len <= 0
400404 then return C.Closed
401− else C.sourcePull src'
402− , C.sourceClose = return ()
403− }
405+ else return src')
406+ (return ())
404407 return $ wrap $ src C.$= isolate
405408 return Request
406409 { requestMethod = method
@@ -578,13 +581,9 @@ sendResponse th req conn r = sendResponse' r
578581 -- functions below. Should lessen greatly the GC burden (I hope)
579582 needsChunked' = needsChunked hs
580583 chunk :: C.Conduit Builder (ResourceT IO) Builder
581− chunk = C.Conduit
582− { C.conduitPush = push
583− , C.conduitClose = close
584− }
585− conduit = C.Conduit push close
586− push x = return $ C.Producing conduit [chunkedTransferEncoding x]
587− close = return [chunkedTransferTerminator]
584+ chunk = C.Running push close
585+ push x = C.HaveMore chunk (return ()) (chunkedTransferEncoding x)
586+ close = C.Open C.Closed (return ()) chunkedTransferTerminator
588587
589588parseHeaderNoAttr :: ByteString -> H.Header
590589parseHeaderNoAttr s =
@@ -600,24 +599,22 @@ connSource :: Connection -> T.Handle -> C.Source (ResourceT IO) ByteString
600599connSource Connection { connRecv = recv } th =
601600 src
602601 where
603− src = C.Source
604− { C.sourcePull = do
605− bs <- liftIO recv
606− if S.null bs
607− then return C.Closed
608− else do
609− when (S.length bs >= 2048) $ liftIO $ T.tickle th
610− return (C.Open src bs)
611− , C.sourceClose = return ()
612− }
602+ src = C.SourceM (do
603+ bs <- liftIO recv
604+ if S.null bs
605+ then return C.Closed
606+ else do
607+ when (S.length bs >= 2048) $ liftIO $ T.tickle th
608+ return (C.Open src (return ()) bs))
609+ (return ())
613610
614611-- | Use 'connSendAll' to send this data while respecting timeout rules.
615612connSink :: Connection -> T.Handle -> C.Sink B.ByteString (ResourceT IO) ()
616613connSink Connection { connSendAll = send } th =
617− C.SinkData push close
614+ C.Processing push close
618615 where
619616 close = liftIO (T.resume th)
620− push x = do
617+ push x = C.SinkM $ do
621618 liftIO $ do
622619 T.resume th
623620 send x