[reactive] problem with unamb -- doesn't kill enough threads

Conal Elliott conal at conal.net
Thu Dec 18 16:43:13 EST 2008


I realized in the shower this morning that there's a serious flaw in my
unamb implementation as described in
http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice.
I'm looking for ideas for fixing the flaw.  Here's the code for racing
computations:

    race :: IO a -> IO a -> IO a
    a `race` b = do v  <- newEmptyMVar
                    ta <- forkPut a v
                    tb <- forkPut b v
                    x  <- takeMVar  v
                    killThread ta
                    killThread tb
                    return x

    forkPut :: IO a -> MVar a -> IO ThreadId
    forkPut act v = forkIO ((act >>= putMVar v) `catch` uhandler `catch`
bhandler)
     where
       uhandler (ErrorCall "Prelude.undefined") = return ()
       uhandler err                             = throw err
       bhandler BlockedOnDeadMVar               = return ()

The problem is that each of the threads ta and tb may have spawned other
threads, directly or indirectly.  When I kill them, they don't get a chance
to kill their sub-threads.

Perhaps I want some form of garbage collection of threads, perhaps akin to
Henry Baker's paper "The Incremental Garbage Collection of Processes".  As
with memory GC, dropping one consumer would sometimes result is cascading
de-allocations.  That cascade is missing from my implementation.

Or maybe there's a simple and dependable manual solution, enhancing the
method above.

Any ideas?

   - Conal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/reactive/attachments/20081218/663a88be/attachment.htm


More information about the Reactive mailing list