Felipe Almeida Lessa wrote: > I have some code that is not behaving the way I thought it should. > > The gist of it is > > sleeper = > mask_ $ > forkIOWithUnmask $ \restore -> > forever $ > restore sleep `catch` throwBack > > throwBack (Ping tid) = myThreadId >>= throwTo tid . Pong > throwBack (Pong tid) = myThreadId >>= throwTo tid . Ping > > Since (a) throwBack is executed on a masked state, (b) myThreadId is > uninterruptible, and (c) throwTo is uninterruptible, my understanding > is that the sleeper thread should catch all PingPong exceptions and > never let any one of them through.
(c) is wrong, throwTo may block, and blocking operations are interruptible. http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html#v:throwTo explains this in some more detail. The simplest way that throwTo can actually block in your program, as far as I can see, and one that will only affect the threaded RTS, is if the sleeper thread and whichever thread is running the other throwBack are executing on different capabilities; this will always cause throwTo to block. (You could try looking at a ghc event log to find out more.) I last ran into trouble like that with System.Timeout.timeout; for that function I finally convinced myself that uninterruptibleMask is the only way to avoid such problems; then throwTo will not be interrupted by exceptions even when it blocks. Maybe this is the solution for your problem, too. Hope that helps, Bertram _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users