{-# LANGUAGE ForeignFunctionInterface #-} import Foreign import Data.IORef import Control.Concurrent import Control.Exception import System.IO.Unsafe foreign import ccall "wrapper" wrap :: IO () -> IO (FunPtr (IO ())) foreign import ccall "dynamic" invoke :: FunPtr (IO ()) -> IO () {-# NOINLINE m #-} m :: IORef ThreadId m = unsafePerformIO (newIORef (error "m")) main = do id <- myThreadId writeIORef m id raise' <- wrap raise invoke raise' raise = do id <- readIORef m me <- myThreadId forkIO $ do threadDelay 10000; throwTo me (ErrorCall "timeout") throwTo id (ErrorCall "kapow!")