summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/Event
diff options
context:
space:
mode:
authorMerijn Verstraaten <merijn@inconsistent.nl>2013-07-24 19:00:42 +0100
committerAustin Seipp <aseipp@pobox.com>2013-11-07 04:11:22 -0600
commit33ed16bd8b3d95dd18e401a3d64435d8675b5f86 (patch)
treec310d50e0b744a5da631ffc4e4207fa92543de0f /libraries/base/GHC/Event
parent00e04e81fb127d716719a85d9387a98b664b7176 (diff)
downloadhaskell-33ed16bd8b3d95dd18e401a3d64435d8675b5f86.tar.gz
*Really* RTS crash due to bad coercion.
Previous commit only moved the coercion mistake to a different architecture (i.e. underflow could still occur on platforms where Int is smaller than CInt). This patch should definitively deal with all possible combinations. Signed-off-by: Austin Seipp <aseipp@pobox.com>
Diffstat (limited to 'libraries/base/GHC/Event')
-rw-r--r--libraries/base/GHC/Event/Poll.hsc18
1 files changed, 16 insertions, 2 deletions
diff --git a/libraries/base/GHC/Event/Poll.hsc b/libraries/base/GHC/Event/Poll.hsc
index 6d089fb387..572cff6af7 100644
--- a/libraries/base/GHC/Event/Poll.hsc
+++ b/libraries/base/GHC/Event/Poll.hsc
@@ -121,9 +121,23 @@ poll p mtout f = do
then c_pollLoop ptr len (fromIntegral (tout - maxPollTimeout))
else return result
- -- Timeout of c_poll is limited by max value of CInt
+ -- We need to account for 3 cases:
+ -- 1. Int and CInt are of equal size.
+ -- 2. Int is larger than CInt
+ -- 3. Int is smaller than CInt
+ --
+ -- In case 1, the value of maxPollTimeout will be the maxBound of Int.
+ --
+ -- In case 2, the value of maxPollTimeout will be the maxBound of CInt,
+ -- which is the largest value accepted by c_poll. This will result in
+ -- c_pollLoop recursing if the provided timeout is larger.
+ --
+ -- In case 3, "fromIntegral (maxBound :: CInt) :: Int" wil result in a
+ -- negative Int, max will thus return maxBound :: Int. Since poll doesn't
+ -- accept values bigger than maxBound :: Int and CInt is larger than Int,
+ -- there is no problem converting Int to CInt for the c_poll call.
maxPollTimeout :: Int
- maxPollTimeout = fromIntegral (maxBound :: CInt)
+ maxPollTimeout = max maxBound (fromIntegral (maxBound :: CInt))
fromTimeout :: E.Timeout -> Int
fromTimeout E.Forever = -1