summaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorSergei Trofimovich <slyfox@gentoo.org>2014-05-23 23:58:06 +0300
committerSimon Marlow <marlowsd@gmail.com>2014-06-08 11:21:11 +0100
commit9fd507e5758f4141ac2619f0db57136bcab035c6 (patch)
tree2eb2d698e7d0b634804dd1753400395f352eb00e /libraries
parent2f8b4c9330b455d4cb31c186c747a7db12a69251 (diff)
downloadhaskell-9fd507e5758f4141ac2619f0db57136bcab035c6.tar.gz
Raise exceptions when blocked in bad FDs (fixes Trac #4934)
Before the patch any call to 'select()' with 'bad_fd' led to: - unblocking of all threads - hiding exception for 'threadWaitRead bad_fd' The patch fixes both cases in this way: after 'select()' failure we iterate over each blocked descriptor and poll individually to see it's actual status, which is: - READY (move to run queue) - BLOCKED (leave in blocked queue) - INVALID (send an IOErrror exception) Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
Diffstat (limited to 'libraries')
-rw-r--r--libraries/base/GHC/Event/Thread.hs6
1 files changed, 5 insertions, 1 deletions
diff --git a/libraries/base/GHC/Event/Thread.hs b/libraries/base/GHC/Event/Thread.hs
index c599047db6..6e991bfb6c 100644
--- a/libraries/base/GHC/Event/Thread.hs
+++ b/libraries/base/GHC/Event/Thread.hs
@@ -12,9 +12,10 @@ module GHC.Event.Thread
, closeFdWith
, threadDelay
, registerDelay
+ , blockedOnBadFD -- used by RTS
) where
-import Control.Exception (finally)
+import Control.Exception (finally, SomeException, toException)
import Control.Monad (forM, forM_, sequence_, zipWithM, when)
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import Data.List (zipWith3)
@@ -115,6 +116,9 @@ threadWait evt fd = mask_ $ do
then ioError $ errnoToIOError "threadWait" eBADF Nothing Nothing
else return ()
+-- used at least by RTS in 'select()' IO manager backend
+blockedOnBadFD :: SomeException
+blockedOnBadFD = toException $ errnoToIOError "awaitEvent" eBADF Nothing Nothing
threadWaitSTM :: Event -> Fd -> IO (STM (), IO ())
threadWaitSTM evt fd = mask_ $ do