summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-12-20 10:26:24 -0500
committerBen Gamari <ben@smart-cactus.org>2022-12-21 15:41:54 -0500
commit62e6c27fb884ce7ffb8e0513516888d8a40900ed (patch)
tree519ec7ad612a4eb1bb707d2037859c5d2a4374fb
parent5e047effac9228f3bdddb66c9056e86621ccbec8 (diff)
downloadhaskell-wip/setnumcapabilities.tar.gz
base: Fix event manager shutdown race on non-Linux platformswip/setnumcapabilities
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 ()