black hole detection and concurrency

Bertram Felgenhauer bertram.felgenhauer at
Sat Dec 27 19:26:12 EST 2008


Bertram Felgenhauer wrote:
> race :: IO a -> IO a -> IO a

Two quick notes on that function:

> race a b = block $ do
>     v <- newEmptyMVar
>     let t x = x >>= putMVar v

Should be
      let t x = unblock (x >>= putMVar v)

Otherwise the computation 'x' not be interruptible unless it explicitely
uses 'unblock' or a blocking operation like reading an MVar.

>     ta <- forkIO (t a)
>     tb <- forkIO (t b)
>     let cleanup = killThread ta >> killThread tb
>     unblock (do r <- takeMVar v; cleanup; return r)
>         `catch` \e -> case e of
>             ThreadKilled -> do
>                 cleanup
>                 myThreadId >>= killThread
>                 unblock (race a b)

On the other hand, this 'unblock' should have no effect: If we ever
return here, it'll be in a different thread, or after another exception
handler has enabled exceptions for the current thread.

>             e -> throwIO e

Oops. This should call cleanup as well. (I guess it should be done
before the 'case' expression)

              e -> cleanup >> throwIO e


More information about the Glasgow-haskell-users mailing list