Skip to content

closeConnection can swallow IO exceptions and block / hang indefinitely #103

@liminalisht

Description

@liminalisht

closeConnection :: Connection -> IO ()
closeConnection c = do
CE.catch (
withMVar (connWriteLock c) $ \_ -> writeFrame (connHandle c) $ Frame 0 $ MethodPayload $ Connection_close
--TODO: set these values
0 -- reply_code
(ShortString "") -- reply_text
0 -- class_id
0 -- method_id
)
(\ (_ :: CE.IOException) ->
--do nothing if connection is already closed
return ()
)

closeConnection swallows any IO exceptions it might encounter upon sending the close connection message to the server, and then waits on the server indefinitely, expecting the server to send back a connection_closed_ok message.

One problem I see is that if an IO exception is encountered when sending the server the close connection message, there is no reason to expect that the server has properly received the message, and therefore no reason to expect that the server will respond with a connection_closed_ok message.

In such a case, the MVar contents will never become full, and the call to readMVar will block forever. From the readMVar docs:

Atomically read the contents of an MVar. If the MVar is currently empty, readMVar will wait until it is full.

https://www.stackage.org/haddock/lts-18.22/base-4.14.3.0/Control-Concurrent-MVar.html#v:readMVar

I would propose that closeConnection at a minimum be altered such that readMVar is not called if an IO exception is encountered.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions