diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-12-20 10:26:24 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2022-12-21 15:41:54 -0500 |
commit | 62e6c27fb884ce7ffb8e0513516888d8a40900ed (patch) | |
tree | 519ec7ad612a4eb1bb707d2037859c5d2a4374fb | |
parent | 5e047effac9228f3bdddb66c9056e86621ccbec8 (diff) | |
download | haskell-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.hs | 13 |
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 () |