I sent this to beginners but got no responses so I'm hoping someone
here can help. I’ve looked at
https://wiki.haskell.org/Concurrency_demos/Graceful_exit and used(2)
Using throwTo without the use of block and unblock. It runs on 8.2.1
with my limited testing. I can’t find out much about what the > 7.x
GHC replacement for block/unblock is other than mask. What does the
unblock do in acceptConnections'?
Does this method of handling an accept loop still need masking of
async exceptions ? If so where does this need to be done?
acceptLoop :: Socket -> IO ()
acceptLoop sock =
loop = do
-- only safe point in the loop for exceptions
(connected_sock, _) <- accept sock
-- use forkIOWithUnmask: we want the thread to be
interruptable no matter
-- what the inherited masking state is
_thr_id <- forkIOWithUnmask (handle_conn connected_sock)
handle_conn connected_sock unmask =
-- register cleanup action, run the handler in interruptable state to be
-- able to kill the thread.
catch (unmask (handler connected_sock)) (\(_exc ::
SomeException) -> close connected_sock)
> Hi Ömer
>> You need to mask async exceptions between `accept()` and cleanup action
>> registration, because an exception in between these operations will cause the
>> socket to leak.
>> You can take a look at warp's accept loop:
>> https://github.com/yesodweb/wai/blob/master/warp/Network/Wai/Handler/Warp/Run.hs#L211 >>
> Trying to map steps for the code you've pointed me to in bad pseudo code:
> finally (mask >> acceptLoop serverSocket) (close serverSocket)
> acceptLoop =
> sock <- accept serverSock
> forkIO $ do
> finally (unmask >> process sock) (close sock)
> Is this correct?