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

Conal Elliott conal at conal.net
Thu Dec 18 19:10:19 EST 2008


Oh!  I hadn't thought of catch/clean-up/rethrow.  There is a 'finally'
function that takes a clean-up action to be executed even if the main
computation is killed:

    finally :: IO a -> IO b -> IO a

I think this is exactly what I need.  Thanks, Peter!

  - Conal

On Thu, Dec 18, 2008 at 3:15 PM, Peter Verswyvelen <bugfact at gmail.com>wrote:

> I thought that killing a thread was basically done by throwing a
> ThreadKilled exception using throwTo. Can't these exception be caught?
> In C#/F# I usually use a similar technique: catch the exception that kills
> the thread, and perform cleanup. I have no experience with Haskell in that
> regard so most likely I'm missing something here...
>
> 2008/12/18 Conal Elliott <conal at conal.net>
>
>> 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
>>
>>
>>
>> _______________________________________________
>> Reactive mailing list
>> Reactive at haskell.org
>> http://www.haskell.org/mailman/listinfo/reactive
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/reactive/attachments/20081218/df79d86f/attachment.htm


More information about the Reactive mailing list