@@ -138,16 +138,14 @@ procConnections chans sock = forever $ do
138138 let chanMap' = IntMap.insert chanId (chan, (threadId, clientSock):socks) chanMap
139139 putMVar chans (chanId', chanMap')
140140
141−-- This function first extracts a header of type Int64, which determines
141+-- | This function first extracts a header of type Int64, which determines
142142-- the size of the ByteString that follows. The ByteString is then
143143-- extracted from the socket, and then written to the Chan only when
144−-- complete. A length of -1 indicates that the socket has finished
145−-- communicating.
144+-- complete.
146145procMessages :: Chans -> ChanId -> Chan ByteString -> Socket -> IO ()
147146procMessages chans chanId chan sock = do
148147 sizeBS <- recvExact sock 8
149− let size = B.decode sizeBS
150− if size == -1
148+ if BS.null sizeBS
151149 then do
152150 (chanId', chanMap) <- takeMVar chans
153151 case IntMap.lookup chanId chanMap of
@@ -160,6 +158,7 @@ procMessages chans chanId chan sock = do
160158 putMVar chans (chanId', chanMap')
161159 sClose sock
162160 else do
161+ let size = B.decode sizeBS
163162 bs <- recvExact sock size
164163 writeChan chan bs
165164 procMessages chans chanId chan sock
@@ -167,11 +166,16 @@ procMessages chans chanId chan sock = do
167166-- | The result of `recvExact sock n` is a `ByteString` of length `n`, received
168167-- from `sock`. No more bytes than necessary are read from the socket.
169168-- NB: This uses Network.Socket.ByteString.recv, which may *discard*
170−-- superfluous input depending on the socket type.
169+-- superfluous input depending on the socket type. Also note that
170+-- if `recv` returns an empty `ByteString` then this means that the socket
171+-- was closed: in this case, we return the empty `ByteString`.
171172recvExact :: Socket -> Int64 -> IO ByteString
172173recvExact sock n = go BS.empty sock n
173174 where
174175 go bs sock 0 = return bs
175176 go bs sock n = do
176177 bs' <- NBS.recv sock n
177− go (BS.append bs bs') sock (n - BS.length bs')
178+ if BS.null bs'
179+ then return bs'
180+ else go (BS.append bs bs') sock (n - BS.length bs')
181+