Fwd: Safe TCP accept loop

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Fwd: Safe TCP accept loop

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/6927216597a35a9a0d7f2e55cca83fa5b7279ee0/hvrr-comms/src/Network/VRR/Server/TCP/TCPAcceptLoop.hs)
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.
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Safe TCP accept loop

Ömer Sinan Ağacan
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/Run.hs#L211

Hope this helps,

Ömer

2017-10-24 2:08 GMT+03:00 Sumit Raja <[hidden email]>:

> 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/6927216597a35a9a0d7f2e55cca83fa5b7279ee0/hvrr-comms/src/Network/VRR/Server/TCP/TCPAcceptLoop.hs)
> 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.
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Safe TCP accept loop

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/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 =
  unmask
  sock <- accept serverSock
  mask
    forkIO $ do
       mask
       finally (unmask >> process sock) (close sock)
  acceptLoop

Is this correct?

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.
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Safe TCP accept loop

Ö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 <[hidden email]>:

> 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 =
>   unmask
>   sock <- accept serverSock
>   mask
>     forkIO $ do
>        mask
>        finally (unmask >> process sock) (close sock)
>   acceptLoop
>
> Is this correct?
>
> 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.