From: Johan Ur Riise
Subject: with-timeout for CLISP/Linux
Date: 
Message-ID: <87hczeoo1q.fsf@morr.riise-data.net>
(defmacro with-timeout (timeout &rest forms)
  "Signals system::simple-interrupt-condition after <timeout> seconds."
  (let ((result (gensym)))
    `(let ((child-pid (linux:fork)))
       (if (eql 0 child-pid)
           (progn (sleep ,timeout) ;child
                  (linux:kill (linux:getppid) 14)
                  (linux:_exit 0))
           (let ((,result (progn ,@forms))) ;parent
             (linux:kill child-pid 9)
             ,result)))))

I loose the slime-connection if I use it without catching the 
condition. 

So what happens if a SIGINT or a SIGALRM comes while the timeout
is ticking? Probably you think you have a timeout, then a new
condition pops up a while later. The macro should may be be
changed so it unconditionally kills the child.

I am sure there are some other problems too.

Anyway, test:
(handler-case (with-timeout 3 
                (sleep 2)
                :ended) 
  (system::simple-interrupt-condition (c) :timed-out))

=> :ENDED

(handler-case (with-timeout 1 
                (sleep 2)
                :ended) 
  (system::simple-interrupt-condition (c) :timed-out))

=> :TIMED-OUT

From: Stephen Compall
Subject: Re: with-timeout for CLISP/Linux
Date: 
Message-ID: <kq9Ng.212238$Df2.135715@fe05.news.easynews.com>
Johan Ur Riise wrote:
>            (let ((,result (progn ,@forms))) ;parent
>              (linux:kill child-pid 9)
>              ,result)))))

Users of macros with body-forms arguments that advertise answering of
the value of the last form usually expect answering of the *values* of
the last form.  See MULTIPLE-VALUE-LIST, VALUES-LIST, and
MULTIPLE-VALUE-PROG1 for ways to implement this behavior in the
parent-process case.

-- 
Stephen Compall
http://scompall.nocandysw.com/blog
From: Kaz Kylheku
Subject: Re: with-timeout for CLISP/Linux
Date: 
Message-ID: <1158102627.215293.141680@e63g2000cwd.googlegroups.com>
Stephen Compall wrote:
> Johan Ur Riise wrote:
> >            (let ((,result (progn ,@forms))) ;parent
> >              (linux:kill child-pid 9)
> >              ,result)))))
>
> Users of macros with body-forms arguments that advertise answering of
> the value of the last form usually expect answering of the *values* of
> the last form.  See MULTIPLE-VALUE-LIST, VALUES-LIST, and
> MULTIPLE-VALUE-PROG1 for ways to implement this behavior in the
> parent-process case.

Two birds, one stone:

  (unwind-protect (progn ,@forms) (linux:kill child-pid 9))
From: Johan Ur Riise
Subject: Re: with-timeout for CLISP/Linux
Date: 
Message-ID: <87d59lo98r.fsf@morr.riise-data.net>
"Kaz Kylheku" <········@gmail.com> writes:

> Stephen Compall wrote:
> > Johan Ur Riise wrote:
> > >            (let ((,result (progn ,@forms))) ;parent
> > >              (linux:kill child-pid 9)
> > >              ,result)))))
> >
> > Users of macros with body-forms arguments that advertise answering of
> > the value of the last form usually expect answering of the *values* of
> > the last form.  See MULTIPLE-VALUE-LIST, VALUES-LIST, and
> > MULTIPLE-VALUE-PROG1 for ways to implement this behavior in the
> > parent-process case.
> 
> Two birds, one stone:
> 
>   (unwind-protect (progn ,@forms) (linux:kill child-pid 9))

Ok, now it reads:

(defmacro with-timeout (timeout &rest forms)
  "Signals system::simple-interrupt-condition after <timeout> seconds. 
Note: you might loose the connection with slime if you dont catch it"
  (let ((result (gensym)))
    `(let ((child-pid (linux:fork)))
       (if (eql 0 child-pid)
           (progn (sleep ,timeout) ;child
                  (linux:kill (linux:getppid) 14)
                  (linux:_exit 0))
           (unwind-protect (progn ,@forms) 
             (linux:kill child-pid 9))))))

;; test
(handler-case (with-timeout .3 (sleep .2) :ended) 
        (system::simple-interrupt-condition (c) :timed-out))
(handler-case (with-timeout .1 (sleep .2) :ended) 
        (system::simple-interrupt-condition (c) :timed-out))
From: Johan Ur Riise
Subject: Re: with-timeout for CLISP/Linux
Date: 
Message-ID: <878xk9o7rs.fsf@morr.riise-data.net>
Johan Ur Riise <·····@riise-data.no> writes:

> "Kaz Kylheku" <········@gmail.com> writes:
> 
> > Stephen Compall wrote:
> > > Johan Ur Riise wrote:
> > > >            (let ((,result (progn ,@forms))) ;parent
> > > >              (linux:kill child-pid 9)
> > > >              ,result)))))
> > >
> > > Users of macros with body-forms arguments that advertise answering of
> > > the value of the last form usually expect answering of the *values* of
> > > the last form.  See MULTIPLE-VALUE-LIST, VALUES-LIST, and
> > > MULTIPLE-VALUE-PROG1 for ways to implement this behavior in the
> > > parent-process case.
> > 
> > Two birds, one stone:
> > 
> >   (unwind-protect (progn ,@forms) (linux:kill child-pid 9))
> 
> Ok, now it reads:

Using c.l.l as my source code management system...

#+clisp
(defmacro with-timeout (timeout &rest forms)
  "Signals system::simple-interrupt-condition after <timeout> seconds.
Note: you might loose the connection with slime if you dont catch it"
  (let ((child-pid (gensym)))
    `(let ((,child-pid (linux:fork)))
       (if (eql 0 ,child-pid)
           (progn (sleep ,timeout) ;child
                  (linux:kill (linux:getppid) 14)
                  (linux:_exit 0))
           (unwind-protect (progn ,@forms) ;parent
             (linux:kill ,child-pid 9))))))

;; test
(handler-case (with-timeout .3 (sleep .2) :ended)
  (system::simple-interrupt-condition () :timed-out))
=> :ENDED

(handler-case (with-timeout .1 (sleep .2) :ended)
  (system::simple-interrupt-condition () :timed-out))
=> :TIMED-OUT