CoExec in Haskell

Posted on Saturday, 03 May 2008 at 13:39.

Last week I built a simple MUD client in Haskell. It’s already working pretty well; I hope to be able to tell more about it soon.

One of the things I needed for it was create several threads, then wait for these threads to finish. Since every thread created in Haskell is a daemon thread, the waiting needs to be done explicitly. Therefore, I thought it’d be nice if we had a coExec :: [IO ()] -> IO () which concurrently runs the actions in its argument and doesn’t return until they finish:

module CoExec where

import Control.Exception
import Control.Concurrent

coExec :: [IO ()] -> IO ()
coExec [] = return ()
coExec (x:xs) = do
  -- Create lock.
  lock <- newEmptyMVar
  -- Spawn child; release lock when child is done.
  forkIO (x `finally` putMVar lock ())
  -- CoExec the other jobs.
  coExec xs
    -- Wait for child to finish.
  takeMVar lock

Let's see if it works:

*CoExec> (coExec . map putStrLn) ["aap", "noot", "mies", "wim", "zus", undefined]
aanmwz<interactive>: Prelude.undefined

Beautiful! ;-)

Leave a comment!

Martijn loves to receive comments! Add yours by filling out the fields below.