[Haskell-cafe] Cleaning up threads

Gregory Collins greg at gregorycollins.net
Tue Sep 14 20:23:42 EDT 2010

Mitar <mmitar at gmail.com> writes:

> Hi!
> On Tue, Sep 14, 2010 at 11:46 PM, Bas van Dijk <v.dijk.bas at gmail.com> wrote:
>> Note that killing the main thread will also kill all other threads. See:
> Yes. But how does those other threads have time to cleanup is my question.

What we do in Snap is this: the master thread has a catch handler which
catches the AsyncException generated by the call to killThread. When we
get this, we instruct any service loop threads to exit, and they all
wait for service threads to terminate (currently by sleep-polling a
connections table, which I should probably fix...). Then the master
thread exits by just returning.

Note that I think the "main thread being killed kills all threads" issue
can be circumvented by using a little gadget like this:

    someWorkToDo :: IO ()
    someWorkToDo = someStuff `catch` cleanupHandler

    main :: IO ()
    main = do
        mv  <- newEmptyMVar
        tid <- forkIO (someWorkToDo `finally` putMVar mv ())

        -- wait on thread to finish; any exception here is probably an
        -- AsyncException, so kill the someWorkToDo master thread
        -- yourself and wait on the mvar again

        takeMVar mv `catch` \(e::SomeException) -> do
            killThread tid
            takeMVar mv

At least, this is what we do in our webserver, and it seems to work
fine -- users complain about the delay involved in our slow cleanup
handler when they ctrl-c the server. :)

Gregory Collins <greg at gregorycollins.net>

More information about the Haskell-Cafe mailing list