asynchronous exceptions

On 05 April 2006 16:46, Marcin 'Qrczak' Kowalczyk wrote:
> "Simon Marlow" <simonmar at microsoft.com> 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