
On 05 April 2006 16:46, Marcin 'Qrczak' Kowalczyk wrote:
"Simon Marlow"
writes: I'm not sure whether asynchronous exceptions should be in Haskell'. I don't feel entirely comfortable about the "interruptible operations" facet of the design,
I designed that differently for my language. There is a distinct "synchronous mode" where asynchronous exceptions are handled by certain operations only, similarly to POSIX deferred mode of thread cancellation. This allows to use blocking operations without being interrupted.
I think it's unnecessary to treat signals in the way you do - you're assuming that a signal interrupts the current thread and runs a new computation (the signal handler) on the same stack, completely blocking the interrupted thread until the signal handler completes. This is the wrong way to view signal handlers, IMO: they should run in completely separate threads (perhaps a higher priority thread, if possible). + you don't have to block signals just because you happen to be holding a mutex. Synchronisation with a signal handler is just synchronisation with another thread. + protecting the invariants of your mutable state from signal handlers is done using existing mechanisms for sharing mutable state with other threads + you can't just raise an exception from a signal handler, it has to be thrown to another thread. This raises the need for asynchronous exception handling and block/unblock, but that's simpler than signal handling. Basically, the whole situation is much simpler if signals don't *interrupt* threads. Of course I'm talking here about signals that are truly asynchronous. Synchronous signals should ideally just turn into exceptions directly (synchronous exceptions, of course). I agree with your assessment of the problems with interruptible operations in GHC: that it is impossible to completely block async exceptions across a computation. We could certainly add a way to do this. Is that the substance of your objection to GHC's async exception mechanism? I couldn't completely follow all the arguments from your paper (some example code would help!). Suppose we had block/unblock count scopes, as you suggested in your paper. We considered this at the time of the design, but rejected it because we wanted the property that unblock always unblocks exceptions. I must admit I can't see why this is an important property, now that I think about it; for modularity it seems you want the opposite. What about interruptible operations? We certainly want operations that are interruptible inside a block - that's the whole point. But we might also want to perform these same operations in a non-interruptible way, as you argued. So I propose also adding blockAll :: IO () -> IO () which is just like block, but it doesn't allow interruptible operations either. This gives us the full range of synchronous/asynchronous/blocked that pthreads has. Cheers, Simon