asynchronous exceptions (was: RE: Concurrency)
simonmar at microsoft.com
Wed Apr 5 10:24:03 EDT 2006
On 05 April 2006 12:47, David Roundy wrote:
> On Tue, Apr 04, 2006 at 01:33:39PM +0100, Simon Marlow wrote:
>> The fact that throwTo can interrupt a takeMVar, but can't interrupt a
>> foreign call, even a concurrent one, is a bit strange. We have this
>> odd situation in GHC right now where throwTo can interrupt
>> threadDelay on Unix, but not on Windows because threadDelay maps
>> directly to a foreign call to Sleep() on Windows. To fix this I
>> have to implement the I/O manager thread on Windows (I should do
>> this anyway, though). [...]
>> The only guarantee you can give is "the exception isn't delayed
>> indefinitely, unless the target thread remains inside a block". Just
>> like the fairness property for MVars.
> I think this is fine. There's no need for strong guarantees that
> asynchronous exceptions are delivered soon or interrrupt any
> particular external function calls, or even interrupt particular
> standard library functions. At least to me, that's what makes them
> asynchronous. In other words, I wouldn't mind cooperative
> asynchronous function calls. Which is to say, that I don't see any
> reason the standard IO library shouldn't be allowed (by the standard)
> to use block in all its calls.
Yes, maybe it's ok. The nice thing about the way block works right now
is that it doesn't quite block all asynchronous exceptions, it actually
turns them into synchronous exceptions which are much more tractable.
For example, in GHC's IO library I couldn't face the prospect of
scrutinising every line of code for exception-safety, so I just put a
block around everything that modifies Handle state. This isn't nearly
as bad as it sounds, because any operation that blocks inside an I/O
operation is still interruptible, but because we know which operations
those are, we can be prepared to handle the exceptions. In fact, since
the operations that block are mostly the I/O operations themselves,
we're already well prepared for handling exceptions there anyway. So it
all works out nicely.
Concurrency abstractions built from MVars suffer a bit from
async-exception-safety. The right way is to build these abstractions
using the exception-safe withMVar & modifyMVar family, but they impose
an overhead. Fortunately STM is exactly the right solution here.
More information about the Haskell-prime