# How to write a proper forking bracket function

**URL:** https://discourse.haskell.org/t/how-to-write-a-proper-forking-bracket-function/1012
**Category:** Learn
**Created:** [December 18, 2019, 12:02am UTC](https://discourse.haskell.org/t/how-to-write-a-proper-forking-bracket-function/1012 "2019-12-18T00:02:20Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![chris-martin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/chris-martin/32/157_2.png) [@chris-martin](https://discourse.haskell.org/u/chris-martin)
#### Post date: [December 18, 2019, 12:02am UTC](https://discourse.haskell.org/t/how-to-write-a-proper-forking-bracket-function/1012/1 "2019-12-18T00:02:21Z")

</div>

I’m working with a common server pattern:

1. Accept a client socket
2. Fork a new thread to do some action with the socket
3. Ensure that the socket always gets closed once the thread ends

On the surface this seems _really_ similar to what [bracket](https://hackage.haskell.org/package/base-4.10.1.0/docs/Control-Exception-Base.html#v:bracket) does, but the forking throws a wrench into it.

Here’s my attempt, largely based on some code from [network-simple](https://hackage.haskell.org/package/network-simple-0.4.5/docs/src/Network.Simple.TCP.html#acceptFork), to abstract this into a general function:

```haskell
bracketFork
    :: IO resource
        -- ^ Runs first, in the current thread
    -> (resource -> IO a)
        -- ^ Runs last, might run in either thread
    -> (resource -> IO b)
        -- ^ Runs in a new thread
    -> IO ThreadId

bracketFork open close action = mask $ \restore ->
  do
    resource <- restore open

    let a = action resource >> return ()
    let b = close resource

    forkIO (restore a `finally` b) `onException` b

```

I still have a really hard time reasoning about exception masking, so I’m hoping somebody can check my work here!

- Can we be sure that `close` always runs?
- Can we be sure that `close` cannot run twice?

And then, if we are confident that this code is correct (or if we can fix it), I’m wondering if there is an appropriate library that might welcome the addition of this function? (Or does it already exist somewhere?) I think masking is a _really_ difficult subject, and so the more of these patterns we can get into libraries, the better, in my opinion.

---

<div class="post-metadata">

### Author: ![chris-martin](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/chris-martin/32/157_2.png) [@chris-martin](https://discourse.haskell.org/u/chris-martin)
#### Post date: [December 18, 2019, 12:55am UTC](https://discourse.haskell.org/t/how-to-write-a-proper-forking-bracket-function/1012/2 "2019-12-18T00:55:25Z")

</div>

Some feedback from [Yuras Shumovich](https://twitter.com/shumovichy/status/1207093768182288386):

- `forkIO` never throws, so the `onException` part wasn’t necessary.
- Now using `forkIOWithUnmask` instead of `forkIO`, because it seems likely that you always want the action to run with async exceptions unmasked, not for the action in the thread to inherit the masking state from the context in which `bracketFork` was used.

The revised function:

```haskell
bracketFork open close action =
    mask_ $
      do
        resource <- open

        forkIOWithUnmask $ \unmask ->
            unmask (action resource >> return ())
            `finally`
            close resource

```

Or, looking at the definition of [finally](https://hackage.haskell.org/package/base-4.10.1.0/docs/src/Control.Exception.Base.html#finally), I think this would be equivalent and slightly more straightforward:

```haskell
bracketFork open close action =
    mask_ $
      do
        resource <- open

        let a = action resource >> return ()
            b = close resource >> return ()

        forkIOWithUnmask $ \unmask ->
            (unmask a `onException` b) >> b

```

* * *

Edit: Alternatively, this should be the same thing, written more clearly, I think.

```haskell
{- | Like 'bracket', except the action and the cleanup
     take place in a newly-forked thread. -}
bracketFork ::
       IO resource -- ^ The first action, runs in the current thread
    -> (resource -> IO a) -- ^ A final action that runs in the forked thread,
                          -- with async exceptions masked
    -> (resource -> IO b) -- ^ Action that runs in the forked thread,
                          -- with async exceptions unmasked
    -> IO ThreadId

bracketFork open close action =
    mask_ $
      do
        resource <- open
        action resource `forkUnmaskedFinally` close resource

{- | Like 'forkFinally', except the action always runs
     with async exceptions unmasked. -}
forkUnmaskedFinally ::
       IO a -- ^ Action that runs in the forked thread,
            -- with async exceptions unmasked
    -> IO b -- ^ A final action that runs in the forked thread,
            -- with async exceptions masked
    -> IO ThreadId

forkUnmaskedFinally action close =
    mask_ $ forkIOWithUnmask $ \unmask ->
      do
        unmask action `onException` close
        close
        return ()

```

---

<div class="post-metadata">

### Author: ![palik](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/palik/32/32_2.png) [@palik](https://discourse.haskell.org/u/palik)
#### Post date: [December 18, 2019, 7:57am UTC](https://discourse.haskell.org/t/how-to-write-a-proper-forking-bracket-function/1012/3 "2019-12-18T07:57:42Z")

</div>

See chapters 8 and 9 in [Parallel and Concurrent Programming in Haskell](https://www.oreilly.com/library/view/parallel-and-concurrent/9781449335939/#toc-start)
