WITH-TIMEOUT -- aside from being a nasty source of asynch interrupts,
is also pretty much impossible to nest sanely, which also means that
library code that uses it is fundamentally broken.
(with-timeout 1.0 (handler-case (with-timeout 4.0 (sleep 2))
I'm thinking we should deprecate it, and provide something like this instead:
(defmacro with-timeout-handler ((seconds timeout-form) &body body)
"Runs BODY as an implicit PROGN with timeout of SECONDS. If
timeout occurs before BODY has finished, BODY is unwound and
TIMEOUT-FORM is executed with its values returned instead.
Note that BODY is unwound asynchronously when a timeout occurs,
so unless all code executed during it -- including anything
down the call chain -- is asynch unwind safe, bad things will
happen. Use with care."
(alexandria:with-gensyms (exec unwind timer timeout block)
(flet ((,unwind ()
(declare (dynamic-extent #',exec #',unwind))
(let ((,timer (sb-ext:make-timer #',unwind)))
(declare (dynamic-extent ,timer))
(sb-ext:schedule-timer ,timer ,seconds)
(return-from ,block ,timeout-form)))))