Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 0.2.0, 0.2.0.1, 0.2.0.2, 0.3.0, 0.3.0.1
    • Fix Version/s: None

      Description

      The following code in `Network.Transport.Util` is unsafe with regard to asynchronous exceptions. If an asynchronous exception is thrown to the forked thread before the endpoint address is put to the `addr` MVar then the final `takeMVar` will dead-lock:

      ```haskell
      spawn :: Transport -> (EndPoint -> IO ()) -> IO EndPointAddress
      spawn transport proc = doo
      addr <- newEmptyMVar
      forkIO $ do
      Right endpoint <- newEndPoint transport
      putMVar addr (address endpoint)
      proc endpoint
      takeMVar addr
      ```

      One way to solve this is using a combination of `mask` and `try`. However a way more simple implementation is:

      ```haskell
      spawn :: Transport -> (EndPoint -> IO ()) -> IO EndPointAddress
      spawn transport proc = do
      Right endpoint <- newEndPoint transport
      forkIO $ proc endpoint
      return $ address endpoint
      ```

      Since the original code has to wait for the completion for `newEndPoint` anyway we could just as well execute it in the main thread and only execute `proc endpoint` in a separate thread. No need for an `MVar` so no posibility of dead-lock.

      However since this code is so simple I wonder if there's actually a need for this combinator. Is it used anywhere? If not, I propose to remove it.

        Attachments

          Activity

            People

            • Assignee:
              edsko Edsko de Vries
              Reporter:
              basvandijk basvandijk
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated: