summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-12-20 10:26:24 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-12-22 23:40:32 -0500
commit35267f077ac226d4fbe3f14fce2dd240fb61e188 (patch)
treebd59fff53fc59581bf18823cbff79d23997b8267
parent02ed7d783244bd95ee897825650426de6f5fb3e2 (diff)
downloadhaskell-35267f077ac226d4fbe3f14fce2dd240fb61e188.tar.gz
base: Fix event manager shutdown race on non-Linux platforms
During shutdown it's possible that we will attempt to use a closed fd to wakeup another capability's event manager. On the Linux eventfd path we were careful to handle this. However on the non-Linux path we failed to do so. Fix this.
-rw-r--r--libraries/base/GHC/Event/Control.hs13
1 files changed, 10 insertions, 3 deletions
diff --git a/libraries/base/GHC/Event/Control.hs b/libraries/base/GHC/Event/Control.hs
index d80e054182..83b64fbb47 100644
--- a/libraries/base/GHC/Event/Control.hs
+++ b/libraries/base/GHC/Event/Control.hs
@@ -50,7 +50,7 @@ import System.Posix.Types (Fd)
import Foreign.C.Error (throwErrnoIfMinus1, eBADF)
import Foreign.C.Types (CULLong(..))
#else
-import Foreign.C.Error (eAGAIN, eWOULDBLOCK)
+import Foreign.C.Error (eAGAIN, eWOULDBLOCK, eBADF)
#endif
data ControlMessage = CMsgWakeup
@@ -211,8 +211,15 @@ sendWakeup c = do
_ | n /= -1 -> return ()
| otherwise -> do
errno <- getErrno
- when (errno /= eAGAIN && errno /= eWOULDBLOCK) $
- throwErrno "sendWakeup"
+ isDead <- readIORef (controlIsDead c)
+ case () of
+ _ -- Someone else has beat us to waking it up
+ | errno == eAGAIN -> return ()
+ | errno == eWOULDBLOCK -> return ()
+ -- we are shutting down
+ | errno == eBADF && isDead -> return ()
+ -- something bad happened
+ | otherwise -> throwErrno "sendWakeup"
#endif
sendDie :: Control -> IO ()