On 10/11/2010 13:39, Mitar wrote:

I know that (I read one post from you some time ago). It is in TODO
commend before this code. I am waiting for GHC 7.0 for this because I
do not like current block/unblock approach.

Because blocked parts can still be interrupted, good example of that
is takeMVar. The other is (almost?) any IO. So if code would be:

block $ forkIO $ do
   putStrLn "Forked"
   (unblock doSomething) `finally` (putMVar terminated ())

There is a chance that putStrLn gets interrupted even with block.

The new async exceptions API isn't going to significantly change things in this area. You still have interruptible operations that can receive async exceptions, and you don't know when you call an IO function in a library whether it uses interruptible operations or not.

The new API means that things like withMVar that previously would unblock async exceptions even when called inside block no longer do that. But that doesn't affect whether a library function that you have no control over can raise async exceptions or not.

You can use maskUninterruptible in GHC 7, but that is not generally recommended, because of the danger that you make your program unresponsive to ^C indefinitely. If you can be sure that the the code will only be blocked for a short time, then maskUninterruptible might be justified, but I think that case is rare. e.g. putStrLn could certainly block indefintely.

So let's be clear about this. Inside mask (previously block), the following things can raise asynchronous exceptions:

 - interruptible operations (MVar operations, throwTo, atomically)

Since we can't be certain that an IO operation from a library does not invoke any interruptible operations, we have to assume that all IO functions from libraries can raise async exceptions.

Well, maybe that's a bit conservative. If it were really true then there wouldn't be much point in mask at all, since the only things you can meaningfully do inside IO involve calling library functions. So we should say there are a few things that you can do that guarantee not to call any interruptible operations:

 - IORef operations
 - STM transactions that do not use retry
 - everything from the Foreign.* modules

and probably some other things. Maybe we should put this list in the documentation.

Cheers,
        Simon



 So
for me it is better to have a big TODO warning before the code than to
use block and believe that this is now fixed. And when I will add some
code one year later I will have problems. Of course I could add a
comment warning not to add any IO before finally. But I want to have a
reason to switch to GHC 7.0. ;-)

I am using such big hack for this:

-- Big hack to prevent interruption: it simply retries interrupted computation
uninterruptible :: IO a ->  IO a
uninterruptible a = block $ a `catch` (\(_ :: SomeException) ->
uninterruptible a)

So I can call "uninterruptible $ takeMVar terminated" and be really
sure that I have waited for thread to terminate. Not that thread in
its last breaths send me some exception which interrupted me waiting
for it and thus not allowing it to terminate properly. Of course if
you now that you do not want that your waiting is interrupted in any
way. Maybe there could be an UserInterrupt exception to this
uninterruptible way of handling exceptions. ;-)

I've made this same error and have seen others make it too. For this
reason I created the threads[1] package to deal with it once and for
all.

I know. I checked it. But was put off by mention of "unsafe".

Strange. It would help if you could show more of of your code.

I am attaching a sample program which shows this. I am using 6.12.3 on
both Linux and Mac OS X. And I run this program with runhaskell
Test.hs. Without "throwIO ThreadKilled" it outputs:

Test.hs: MyTerminateException
MVar was successfully taken

With "throwIO ThreadKilled" is as expected, just:

MVar was successfully taken

So MVar is filled. What means that thread gets exception after that.
But there is nothing after that. ;-) (At least nothing visible.)


Mitar



_______________________________________________
Glasgow-haskell-users mailing list
glasgow-haskell-us...@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to