asynchronous exceptions

Marcin 'Qrczak' Kowalczyk qrczak at
Thu Apr 6 19:36:12 EDT 2006

"Simon Marlow" <simonmar at> writes:

> 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).

This can be emulated in my model: by designating a thread for system
signals, possibly even letting it spawn a new thread for each signal.

Most Unix signals are supposed to abort the process however, and thus
a mechanism for aborting one thread from another is needed anyway.
I think async exceptions are not that much easier than
async signals.

Async signals include the ability to pause threads in safe points,
which is needed for SIGSTOP / SIGTSTP and for my fork() wrapper. This
is not archievable with signals spawning threads + async exceptions.

>   + 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.

It's still very probable that taking a mutex coincides with the need
to block async exceptions: an async exception in the middle of a
critical section implies a danger of leaving data in an inconsistent
state. Reasons for automatic blocking of async signals carry over to
async exceptions.

> 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?

Regarding interruptible operations, this and one more thing that I
haven't written there:

The fact that some function uses an interruptible operation internally
is a visible aspect of its behavior, both in GHC design and in mine.
This means that choosing which operations are interruptible should be
done carefully: even if some operation blocks the thread, it might be
a bad choice for an interruption point, because usage of some blocking
operations should better not have to be exposed. In my case such
blocking but uninterruptible operations include waiting for a mutex,
and waiting for a lazy variable, among others.

But Concurrent Haskell uses a single construct of MVars as mutexes,
semaphores, or communication channels. The runtime can't recognize the
pattern of usage to distinguish these cases.

   __("<         Marcin Kowalczyk
   \__/       qrczak at

More information about the Haskell-prime mailing list