diff options
-rw-r--r-- | libraries/base/Control/Exception/Base.hs | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/libraries/base/Control/Exception/Base.hs b/libraries/base/Control/Exception/Base.hs index a390418458..0b8d822b58 100644 --- a/libraries/base/Control/Exception/Base.hs +++ b/libraries/base/Control/Exception/Base.hs @@ -214,13 +214,21 @@ onException io what = io `catch` \e -> do _ <- what -- -- > withFile name mode = bracket (openFile name mode) hClose -- --- Implementation of bracket is using 'mask', which means that the release --- handler should be uninterruptible to run to completion in presence of --- asynchronous exceptions. 'hClose' is uninterruptible if used --- non-concurrently, closing a socket (from \"network\" package) is --- uninterruptible as well, an example of interruptible close handler is --- 'killThread' which should be wrapped using 'uninterruptibleMask_' when used --- with 'bracket'. Comments in 'uninterruptibleMask' still aply. +-- Bracket wraps the release action with 'mask', which is sufficient to ensure +-- that the release action executes to completion when it does not invoke any +-- interruptible actions, even in the presence of asynchronous exceptions. For +-- example, `hClose` is uninterruptible when it is not racing other uses of the +-- handle. Similarly, closing a socket (from \"network\" package) is also +-- uninterruptible under similar conditions. An example of an interruptible +-- action is 'killThread'. Completion of interruptible release actions can be +-- ensured by wrapping them in in 'uninterruptibleMask_', but this risks making +-- the program non-responsive to @Control-C@, or timeouts. Another option is to +-- run the release action asynchronously in its own thread: +-- +-- > void $ uninterruptibleMask_ $ forkIO $ do { ... } +-- +-- The resource will be released as soon as possible, but the thread that invoked +-- bracket will not block in an uninterruptible state. -- bracket :: IO a -- ^ computation to run first (\"acquire resource\") |