diff options
author | Merijn Verstraaten <merijn@inconsistent.nl> | 2013-07-24 19:00:42 +0100 |
---|---|---|
committer | Austin Seipp <aseipp@pobox.com> | 2013-11-07 04:11:22 -0600 |
commit | 33ed16bd8b3d95dd18e401a3d64435d8675b5f86 (patch) | |
tree | c310d50e0b744a5da631ffc4e4207fa92543de0f /libraries/base/GHC/Event | |
parent | 00e04e81fb127d716719a85d9387a98b664b7176 (diff) | |
download | haskell-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.hsc | 18 |
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 |