Hi,
Do any LispWorks people have a simple macro to try to run a form which
will time out with some kind of condition if the form (or body)
doesn't return in some amount of time?
thanks,
dave
Dave Bakhash wrote:
> Hi,
>
> Do any LispWorks people have a simple macro to try to run a form which
> will time out with some kind of condition if the form (or body)
> doesn't return in some amount of time?
Taken (modified) from my ACL-COMPAT module of Portable AllegroServe:
(defun invoke-with-timeout (timeout bodyfn timeoutfn)
(block timeout
(let* ((process mp:*current-process*)
(timer (mp:make-timer
#'(lambda ()
(mp:process-interrupt
process
#'(lambda ()
(return-from timeout
(funcall timeoutfn))))))))
(mp:schedule-timer-relative timer timeout)
(unwind-protect (funcall bodyfn)
(mp:unschedule-timer timer)))))
(defmacro with-timeout ((seconds &body timeout-forms) &body body)
(let ((-body-form- (gensym "WT-BODY-"))
(-timeout-form- (gensym "WT-TIMEOUT-")))
`(flet ((,-body-form- () ,@body)
(,-timeout-form- () ,@timeout-forms))
(invoke-with-timeout ,seconds #',-body-form-
#',-timeout-form-))))
You can test it with:
(with-timeout (5 (print 'timeout))
(sleep 10))
and
(with-timeout (10 (print 'timeout))
(sleep 5))
ciao,
Jochen
In article <················@dataheaven.de>, Jochen Schmidt wrote:
>(defmacro with-timeout ((seconds &body timeout-forms) &body body)
> (let ((-body-form- (gensym "WT-BODY-"))
> (-timeout-form- (gensym "WT-TIMEOUT-")))
> `(flet ((,-body-form- () ,@body)
> (,-timeout-form- () ,@timeout-forms))
> (invoke-with-timeout ,seconds #',-body-form-
> #',-timeout-form-))))
Why the gensyms and flet, when you can just use two lambda expressions?
(defmacro with-timeout ((seconds &body timeout-forms) &body body)
`(invoke-with-timeout ,seconds #'(lambda () ,@body)
#'(lambda () ,@timeout-forms)))
Do you find that using local functions with gensym names that have
descriptive prefixes enhances readability of the expanded form?
Kaz Kylheku wrote:
> In article <················@dataheaven.de>, Jochen Schmidt wrote:
>
>>(defmacro with-timeout ((seconds &body timeout-forms) &body body)
>> (let ((-body-form- (gensym "WT-BODY-"))
>> (-timeout-form- (gensym "WT-TIMEOUT-")))
>> `(flet ((,-body-form- () ,@body)
>> (,-timeout-form- () ,@timeout-forms))
>> (invoke-with-timeout ,seconds #',-body-form-
>> #',-timeout-form-))))
>>
>
> Why the gensyms and flet, when you can just use two lambda expressions?
>
> (defmacro with-timeout ((seconds &body timeout-forms) &body body)
> `(invoke-with-timeout ,seconds #'(lambda () ,@body)
> #'(lambda () ,@timeout-forms)))
>
> Do you find that using local functions with gensym names that have
> descriptive prefixes enhances readability of the expanded form?
Hm.. I have to say I do not really remember why I did it the way it is
now. But you are right - it is nicer if I simply use two lambdas here...
thanks,
Jochen