summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/Event/Thread.hs
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/base/GHC/Event/Thread.hs')
-rw-r--r--libraries/base/GHC/Event/Thread.hs7
1 files changed, 5 insertions, 2 deletions
diff --git a/libraries/base/GHC/Event/Thread.hs b/libraries/base/GHC/Event/Thread.hs
index 367791354f..a330225622 100644
--- a/libraries/base/GHC/Event/Thread.hs
+++ b/libraries/base/GHC/Event/Thread.hs
@@ -30,7 +30,7 @@ import GHC.Conc.Sync (TVar, ThreadId, ThreadStatus(..), atomically, forkIO,
labelThread, modifyMVar_, withMVar, newTVar, sharedCAF,
getNumCapabilities, threadCapability, myThreadId, forkOn,
threadStatus, writeTVar, newTVarIO, readTVar, retry,throwSTM,STM)
-import GHC.IO (mask_, onException)
+import GHC.IO (mask_, uninterruptibleMask_, onException)
import GHC.IO.Exception (ioError)
import GHC.IOArray (IOArray, newIOArray, readIOArray, writeIOArray,
boundsIOArray)
@@ -104,7 +104,10 @@ closeFdWith close fd = do
mgrs <- flip mapM [low..high] $ \i -> do
Just (_,!mgr) <- readIOArray eventManagerArray i
return mgr
- mask_ $ do
+ -- 'takeMVar', and 'M.closeFd_' might block, although for a very short time.
+ -- To make 'closeFdWith' safe in presence of asynchronous exceptions we have
+ -- to use uninterruptible mask.
+ uninterruptibleMask_ $ do
tables <- flip mapM mgrs $ \mgr -> takeMVar $ M.callbackTableVar mgr fd
cbApps <- zipWithM (\mgr table -> M.closeFd_ mgr table fd) mgrs tables
close fd `finally` sequence_ (zipWith3 finish mgrs tables cbApps)