
1. registerTimeout 2. (fmap Just f) raises an exception, or the thread gets killed otherwise. 3. We enter the `catch` handler, with the corresponding exception. 4. The timeout expires, and the event Manager runs the IO action, i.e. throwTo myTid $ Timeout key 5. And now we have a pending Timeout exception which escapes the 'timeout'. The unregTimeout will come too late.
Bummer! You're right.
But maybe we can catch and ignore a potential pending Timeout exception: (code not tested and profiled yet)
The trouble is that the throwTo action, even though we can no longer stop it using unregisterTimeout, may be delayed arbitrarily. So we'd have to wait for it to arrive. In that regard we have actually lost power compared to spawning a separate thread: throwTo (and thus killThread) explicitely guarantees that if two threads throw exceptions at one another simultaneously, only one of those will arrive, and also that if throwTo returns, the exception has actually been delivered. So if the killThread succeeds, the Timeout exception will never arrive.
Actually the event manager based implementation totally crashes on your example, so again: bummer! I get the following error:
"gotcha: user error (Pattern match failure in do expression at libraries/base/System/Event/Thread.hs:208:9-16)!"
Line 208:
Just mgr <- readIORef eventManager
Yikes! I don't believe that's supposed to happen, but I have no clue how the event manager is initially started - does the RTS invoke ensureIOManagerIsRunning before running main? Best regards, Bertram