
Hi!
On Thu, Nov 18, 2010 at 2:19 PM, Simon Marlow
then it isn't uninterruptible, because the timeout can interrupt it. If you can tolerate a timeout exception, then you can tolerate other kinds of async exception too.
Yes, but semantics are different. I want to tolerate some exception because they are saying I should do this and this (for example user interrupt, or timeout) but I do not want others, which somebody else maybe created and I do not want to care about them.
My main question is then, why do you want to use maskUninterruptible rather than just mask? Can you give a concrete example?
I have written few of them. As I said: timeout and user exceptions. Timeout is for interrupts with which me as a programmer want to limit otherwise uninterruptible code, and user exceptions so that users can limit otherwise uninterruptible code. But in meanwhile I have find an elegant way to solve my problems (very old one in fact). ;-) I have defined such function: uninterruptible :: IO a -> IO a uninterruptible a = mask_ $ a `catch` (\(_ :: SomeException) -> uninterruptible a) with which I wrap takeMVar and other interruptible operations. As they can only be interrupted or succeed they can simply be retried until they succeed. In this way my code is not susceptible to possible dead locks which could happen if I would use maskUninterruptible and for example throw two exceptions between two threads, while they would both be in maskUninterruptible section. In this way I can remain in only masked state, exceptions can still be delivered, but my program flow is not interrupted. Of course function about can be also easily modified to allow user interrupts and timeouts, but not other exceptions. And as I want to use this code only in my cleanup code I do not really care about new exceptions being ignored. Mitar