Dangers of registerTimeout (was: Race-condition in alternative 'System.Timeout.timeout' implementation)
Herbert Valerio Riedel
hvr at gnu.org
Tue Feb 26 10:04:06 CET 2013
Herbert Valerio Riedel <hvr at gnu.org> writes:
[...]
> (bracket (E.registerTimeout em to (throwTo tid ex))
> (E.unregisterTimeout em)
> (\_ -> fmap Just f))
...after some discussion on #ghc, I've realized, that 'registerTimeout'
is dangerous if used improperly; it should be avoided to call any
blocking operation (or throw exceptions) in the timeout-handler, as
otherwise the I/O manager loop stops processing new events (at least
with GHC-7.6.2) until the timeout-action completes; the following code
demonstrates this issue by triggering a neverending timeout-action which
effectively makes the Haskell process non-responsive.
--8<---------------cut here---------------start------------->8---
import Control.Concurrent
import qualified GHC.Event as E
messupEventManager :: IO ()
messupEventManager = do
mv <- newMVar ()
Just em <- E.getSystemEventManager
E.registerTimeout em 5000000 (putStrLn "...blocking NOW!" >> putMVar mv ())
putStrLn "...in about 5 seconds the I/O manager will get stuck..."
--8<---------------cut here---------------end--------------->8---
So maybe a warning in the documentation of registerTimeout may be
appropriate telling users of registerTimeout that care should be taken
to avoid operations blocking for non-negligible time (or throwing
exceptions) in the timeout-handler, as otherwise in the best case the
I/O processing latency suffers and in the worst case the I/O manager may
come to a halt altogether.
cheers,
hvr
More information about the Glasgow-haskell-users
mailing list