
Hi, 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? I've got a version with async running for my specific application (https://bitbucket.org/sumitraja/hvrr/src/6927216597a35a9a0d7f2e55cca83fa5b72...) but I don't know if I need to unmask at any point so was hoping for some guidance. Thanks Sumit

Hi Sumit,
Does this method of handling an accept loop still need masking of async exceptions
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/Ru...
Hope this helps,
Ömer
2017-10-24 2:08 GMT+03:00 Sumit Raja
Hi,
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?
I've got a version with async running for my specific application (https://bitbucket.org/sumitraja/hvrr/src/6927216597a35a9a0d7f2e55cca83fa5b72...) but I don't know if I need to unmask at any point so was hoping for some guidance.
Thanks
Sumit _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

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/Ru...
Trying to map steps for the code you've pointed me to in bad pseudo code: finally (mask >> acceptLoop serverSocket) (close serverSocket) acceptLoop = unmask sock <- accept serverSock mask forkIO $ do mask finally (unmask >> process sock) (close sock) acceptLoop Is this correct? Thanks Sumit

Your pseudo code doesn't look right although I couldn't completely understand
it. You need something like this:
{-# LANGUAGE ScopedTypeVariables #-}
import Network.Socket
import Control.Concurrent
import Control.Exception
acceptLoop :: Socket -> IO ()
acceptLoop sock =
mask_ loop
where
loop = do
-- only safe point in the loop for exceptions
allowInterrupt
(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)
loop
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)
handler connected_sock =
-- fill here
return ()
Ömer
2017-10-25 8:52 GMT+03:00 Sumit Raja
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/Ru...
Trying to map steps for the code you've pointed me to in bad pseudo code:
finally (mask >> acceptLoop serverSocket) (close serverSocket)
acceptLoop = unmask sock <- accept serverSock mask forkIO $ do mask finally (unmask >> process sock) (close sock) acceptLoop
Is this correct?
Thanks Sumit

My apologies I've only just managed to get back to this. I've used
your method described above, thanks for the clear explanation
Now am unable to terminate the async thread that is running the accept
call. Seems to me that Warp relies on the termination of the main
thread to terminate the accept loop - is this correct?
On 25 October 2017 at 17:30, Ömer Sinan Ağacan
Your pseudo code doesn't look right although I couldn't completely understand it. You need something like this:
{-# LANGUAGE ScopedTypeVariables #-}
import Network.Socket import Control.Concurrent import Control.Exception
acceptLoop :: Socket -> IO () acceptLoop sock = mask_ loop where loop = do -- only safe point in the loop for exceptions allowInterrupt
(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)
loop
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)
handler connected_sock = -- fill here return ()
Ömer
2017-10-25 8:52 GMT+03:00 Sumit Raja
: 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/Ru...
Trying to map steps for the code you've pointed me to in bad pseudo code:
finally (mask >> acceptLoop serverSocket) (close serverSocket)
acceptLoop = unmask sock <- accept serverSock mask forkIO $ do mask finally (unmask >> process sock) (close sock) acceptLoop
Is this correct?
Thanks Sumit
participants (2)
-
Sumit Raja
-
Ömer Sinan Ağacan