[Haskell-cafe] Printing of asynchronous exceptions to stderr

Simon Marlow marlowsd at gmail.com
Thu Dec 2 17:36:41 CET 2010


On 13/11/2010 19:08, Bit Connor wrote:
> On Wed, Nov 10, 2010 at 5:48 PM, Simon Marlow<marlowsd at gmail.com>  wrote:
>> [...] 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.
>
> A list would be very helpful. I am specifically interested in knowing about:
>
> - The try family of MVar functions
> - the forkIO function itself

I added the following text to the Control.Exception documentation, in 
the section on "Interruptible operations".  Suggestions for improvements 
are welcome:


It is useful to think of 'mask' not as a way to completely prevent
asynchronous exceptions, but as a filter that allows them to be raised
only at certain places.  The main difficulty with asynchronous
exceptions is that they normally can occur anywhere, but within a
'mask' an asynchronous exception is only raised by operations that are
interruptible (or call other interruptible operations).  In many cases
these operations may themselves raise exceptions, such as I\/O errors,
so the caller should be prepared to handle exceptions arising from the
operation anyway.

Sometimes it is too onerous to handle exceptions in the middle of a
critical piece of stateful code.  There are three ways to handle this
kind of situation:

  * Use STM.  Since a transaction is always either completely executed
    or not at all, transactions are a good way to maintain invariants
    over state in the presence of asynchronous (and indeed synchronous)
    exceptions.

  * Use 'mask', and avoid interruptible operations.  In order to do
    this, we have to know which operations are interruptible.  It is
    impossible to know for any given library function whether it might
    invoke an interruptible operation internally; so instead we give a
    list of guaranteed-not-to-be-interruptible operations below.

  * Use 'uninterruptibleMask'.  This is generally not recommended,
    unless you can guarantee that any interruptible operations invoked
    during the scope of 'uninterruptibleMask' can only ever block for
    a short time.  Otherwise, 'uninterruptibleMask' is a good way to
    make your program deadlock and be unresponsive to user interrupts.

The following operations are guaranteed not to be interruptible:

  * operations on 'IORef' from "Data.IORef"
  * STM transactions that do not use 'retry'
  * everything from the @Foreign@ modules
  * everything from @Control.Exception@
  * @tryTakeMVar@, @tryPutMVar@, @isEmptyMVar@
  * @takeMVar@ if the @MVar@ is definitely full, and conversely 
@putMVar@ if the @MVar@ is definitely empty
  * @newEmptyMVar@, @newMVar@
  * @forkIO@, @forkIOUnmasked@, @myThreadId@


Cheers,
	Simon



More information about the Haskell-Cafe mailing list