+
+-- -----------------------------------------------------------------------------
+-- Asynchronous exceptions
+
+{- $async
+
+Asynchronous exceptions are so-called because they arise due to
+external influences, and can be raised at any point during execution.
+'StackOverflow' and 'HeapOverflow' are two examples of
+system-generated asynchronous exceptions.
+
+The primary source of asynchronous exceptions, however, is
+'throwTo':
+
+> throwTo :: ThreadId -> Exception -> IO ()
+
+'throwTo' (also 'throwDynTo' and 'Concurrent.killThread') allows one
+running thread to raise an arbitrary exception in another thread. The
+exception is therefore asynchronous with respect to the target thread,
+which could be doing anything at the time it receives the exception.
+Great care should be taken with asynchronous exceptions; it is all too
+easy to introduce race conditions by the over zealous use of
+'throwTo'.
+-}
+
+{- $block_handler
+There\'s an implied 'block' around every exception handler in a call
+to one of the 'catch' family of functions. This is because that is
+what you want most of the time - it eliminates a common race condition
+in starting an exception handler, because there may be no exception
+handler on the stack to handle another exception if one arrives
+immediately. If asynchronous exceptions are blocked on entering the
+handler, though, we have time to install a new exception handler
+before being interrupted. If this weren\'t the default, one would have
+to write something like
+
+> block (
+> catch (unblock (...))
+> (\e -> handler)
+> )
+
+If you need to unblock asynchronous exceptions again in the exception
+handler, just use 'unblock' as normal.
+
+Note that 'try' and friends /do not/ have a similar default, because
+there is no exception handler in this case. If you want to use 'try'
+in an asynchronous-exception-safe way, you will need to use
+'block'.
+-}
+
+{- $interruptible
+
+Some operations are /interruptible/, which means that they can receive
+asynchronous exceptions even in the scope of a 'block'. Any function
+which may itself block is defined as interruptible; this includes
+'takeMVar' (but not 'tryTakeMVar'), and most operations which perform
+some I\/O with the outside world.. The reason for having
+interruptible operations is so that we can write things like
+
+> block (
+> a <- takeMVar m
+> catch (unblock (...))
+> (\e -> ...)
+> )
+
+if the 'takeMVar' was not interruptible, then this particular
+combination could lead to deadlock, because the thread itself would be
+blocked in a state where it can\'t receive any asynchronous exceptions.
+With 'takeMVar' interruptible, however, we can be
+safe in the knowledge that the thread can receive exceptions right up
+until the point when the 'takeMVar' succeeds.
+Similar arguments apply for other interruptible operations like
+'IO.openFile'.
+-}
+
+-- -----------------------------------------------------------------------------
+-- Assert
+
+#ifdef __HADDOCK__
+-- | If the first argument evaluates to 'True', then the result is the
+-- second argument. Otherwise an 'Assertion' exception is raised,
+-- containing a 'String' with the source file and line number of the
+-- call to assert.
+--
+-- Assertions can normally be turned on or off with a compiler flag
+-- (for GHC, assertions are normally on unless the @-fignore-asserts@
+-- option is give). When assertions are turned off, the first
+-- argument to 'assert' is ignored, and the second argument is
+-- returned as the result.
+assert :: Bool -> a -> a
+#endif