This is the mail archive of the
guile@cygnus.com
mailing list for the Guile project.
Re: Using async's in Guile.
Mikael Djurfeldt wrote:
> "Bradley M. Kuhn" <bkuhn@ebb.org> writes:
>
> > When I do figure this out, would it be worth it to write a tutorial on using
> > these async functions? I didn't find them documented in the current CVS
> > tree. If I did write such documentation, where would it belong?
> No, at least not yet. Until further notice the asyncs should be
> considered "internal guts" of Guile. It is planned to make a rewrite of
> the signal handling mechanisms when we adapt Guile for POSIX threads.
> Asyncs may not even exist after that.
Hmmm...so, what is the best way now to handle a case where I need a clock to
invoke some function after a specified amount of time.
Right now, I am using a clock implementation that uses SIGALRM underneath.
I would like something a bit more versatile.
Any suggestions? Attached is my current implementation of the clock.
--
- bkuhn@ebb.org - Bradley M. Kuhn - bkuhn@gnu.org -
http://www.ebb.org/bkuhn
; clock-using-alarms.scm -*- Scheme -*-
; Code for engines based on Dorai Sitaram's:
; http://www.cs.rice.edu/~dorai/t-y-scheme/t-y-scheme-Z-H-16.html
; To get a clock in Guile, we use SIGALRM
; We need a consistent clock interface, as the document suggests
; For Guile, we use the alarm mechanism. This allows for only one
; clock at a time. :(
; As stated in Sitaram:
; clock allows the following operations:
; 1) (clock 'set-handler h) sets the interrupt handler to h.
; 2) (clock 'set n) resets the clock's remaining ticks to n,
; returning the previous value.
; Mine works like that, but it is wrapped in an object, so I get:
; ((clock 'set-handler!) h)
; and
; ( (clock 'set-time!) n)
; Note: If you have multiple clocks floating around, they will effect each
; other---if you turn one off, they are all off, and the will all
; call the handler at the minimum of when they were set.
; This problem occurs because there is only one SIGALRM. I have
; searched for a way around this problem but to no avail.
(define make-clock
(lambda ()
(letrec ( (time-amount 'infinity)
(handler '() )
(have-handler #f )
(old-handler (car (sigaction SIGALRM)))
(reset-alarms (lambda ()
; First, if we have and "infinity" clock,
; Then we don't have to have our handler
(if (eq? time-amount 'infinity)
; Set the fact that we don't have
; a handler
(set! have-handler #f)
; Otherwise, as long as time is >= 0,
; note that we have a handler, start
; countdown using alarm
(if (< time-amount 0)
(error
"clock cannot have time < 0")
(begin
(set! have-handler #t)
(alarm time-amount))))) )
)
(sigaction SIGALRM
(lambda (x)
(if have-handler
(handler))
(if (procedure? old-handler) (old-handler x))))
(lambda (message)
(case message
( (set-time!) (lambda (x)
(let ( (old-time time-amount) )
(set! time-amount x)
(reset-alarms)
old-time)))
( (set-handler!) (lambda (x)
(set! have-handler #t)
(set! handler x)
(reset-alarms) ) )
)))))
;******************************************************************************
(define test-clock
(lambda ()
(begin
(let (
(clock1 (make-clock))
(clock2 (make-clock)) )
((clock1 'set-handler!)
(lambda () (writeln "clock1's handler has come!")))
((clock2 'set-handler!)
(lambda () (writeln "clock2's handler has come!")))
( (clock2 'set-time!) 7)
(display "First Time: ")
(display ( (clock1 'set-time!) 5)) (newline)
(sleep 3)
(display "Second Time: ")
(display ( (clock1 'set-time!) 10)) (newline)
(sleep 9)
(display "Handler error should come in one second!!") (newline)
))))