Skip to content

An async exception handler that blocks throwTo until handler finishes running

I'd like to be able to handle an async exception in thread A such that if another thread B calls throwTo, that call blocks until my handler in A has a chance to finish. Currently throwTo only blocks until the exception is "received" (which I don't understand precisely).

My application is a concurrent FIFO queue library, in which a blocked reader must perform a cleanup action on async exceptions, else the next write will be lost:

testBlockedRecovery = do
    c <- newChan
    started <- newEmptyMVar
    rid <- forkIO (putMVar started () >> readChan c)
    takeMVar started >> threadDelay 1000
    throwTo rid ThreadKilled
    -- we race the exception-handler in `readChan` here...
    writeChan c ()
    -- If this write won, then the write was lost and we block indefinitely below:
    readChan c
    putStrLn "OK"

If in my library I could catch the exception in such a way that throwTo blocked until I could handle it, then the test above would pass and the behavior of my Chan would match the standard library.

This might seem like a lame example, but I think this functionality would be very generally useful. It would let you recover to a state using an exception handler such that you can reason in terms of linearizability about the pre- and post- exception states; I assume that's sort of the thinking behind making throwTo synchronous in the first place.

Thanks and please let me know if there's actually a way to do what I'm asking currently, or if any of that wasn't clear.

Trac metadata
Trac field Value
Version 7.8.2
Type FeatureRequest
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information