Timeout implementation for performing operations in the IO monad
with a timeout added. Both using Maybe and exceptions to handle
timeouts are supported.
Timeouts can be implemented in GHC with either a global handler
or a per-timeout thread which sleeps until the timeout. The latter
is used in this module. Blocking on foreign calls can cause
problems as GHC has no way of interrupting such threads.
The module provides a slightly slower alternative implementation
which returns even if the computation has blocked on a foreign
call. This should not be an issue unless -threaded is used.
The timeouts are currently limited to a maximum of about
2000 seconds. This is a feature of threadDelay, but
supporting longer timeouts is certainly possible if
that is desirable.
For nested timeouts there are different ways to implement them:
a) attach an id to the exception so that the catch knows wether it may catch
this timout exception. I've choosen this because overhead is only passing
and incrementing an integer value. A integer wrap araound is possible but
too unlikely to happen to make me worry about it
b) start a new workiing and killing thread so that if the original thread
was run within withTimeOut itself it catches the exception and not an inner
timout. (this is done in withSafeTimeOut, for another reason though)
c) keep throwing exceptions until the the withTimeOut function kills the
killing thread. But consider sequence (forever (timeOut threadDelay 10sec) )
In this case the exception will be called and the next timOut may be entered
before the second Exception has been thrown
All exceptions but the internal TimeOutExceptionI are rethrown in the calling thread