>>>>> "RT" == RT Happe <rthappe@mathematik.uni-freiburg.de> writes:
RT> A possible bug in scsh-0.6.3 beta 4 and questions.
RT> I was trying a variant of Martin Gasbichler's alarm-handler,
RT> http://www.scsh.net/post/alahandler.html, that delivers values by
RT> continuations instead of placeholders. I should probably think some more
RT> about continuations & threads, but anyway, the procedure seems to kill
RT> scsh on its second call. Try and ,open threads locks, then load the code
RT> below and run, e.g., (foo 1) twice. Scsh will die a slow death
RT> terminating with heap overflow.
RT> ;; return the values of THUNK to the success continuation K/SUX if THUNK
RT> ;; executes in time. Otherwise call the 0-ary failure continuation K/FAIL.
RT> (define (execute/timeout thunk millis k/sux k/fail)
RT> (let ((done? #f) (lock (make-lock)))
RT> (spawn (lambda ()
RT> (sleep millis)
RT> (obtain-lock lock)
RT> (if (not done?) (k/fail))
RT> (release-lock lock)))
RT> (spawn (lambda ()
RT> (receive tuple (thunk)
RT> (obtain-lock lock)
RT> (set! done? #t)
RT> (release-lock lock)
RT> (apply k/sux tuple))))))
RT> (define (foo millis)
RT> (call-with-current-continuation
RT> (lambda (cc)
RT> (execute/timeout (lambda () (sleep 256) (values 0 1))
RT> millis
RT> cc
RT> (lambda () (cc 'time 'out))))))
You are applying the continuation of the call to foo in a different
thread. This replaces only the current continuation of the thread but
not the one in the main thread so you effectively duplicate the
continuation. As the REPL is also in this continuation weird things
may happen.
If you start foo in its own thread (and modify execute/timeout to
return 2 values) your example works:
(define (execute/timeout thunk millis k/sux k/fail)
(let ((done? #f) (lock (make-lock)))
(spawn (lambda ()
(sleep millis)
(obtain-lock lock)
(if (not done?) (k/fail))
(release-lock lock)))
(spawn (lambda ()
(call-with-values
thunk
(lambda tuple
(obtain-lock lock)
(set! done? #t)
(release-lock lock)
(apply k/sux tuple)))))
(values 'threads 'started)))
> (spawn (lambda () (receive (a b) (foo 1) (display a))))
Displays threads and time
RT> By the way, how should the executor set up things so that the thread
RT> running the thunk terminates if the latter is slow? The manual describes
RT> only thread suicide (terminate-current-thread), but this won't work as
RT> long as the thunk is running.
The structure threads-internal provides kill-thread! to terminate an
arbitrary thread. The thread terminates before the next procedure call
but no cleanup code will run so there is the danger of not-released
locks.
We plan to provide a SRFI-18 compliant version of the thread system in
a future version of scsh.
--
Martin
|