[plt-scheme] handling user-breaks in MrEd app...

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Oct 30 20:52:03 EST 2002

At Wed, 30 Oct 2002 17:58:45 -0600, Jefferson Provost wrote:
> I'm writing a graphical MrEd app, and though most interaction will be 
> through graphical objects, I want to run a repl for debugging and other 
> stuff.  I don't want to use MrEd's graphical repl, but when I do mred 
> -z, the stdio repl never yields to give events/time to my graphical 
> objects. 

If you have some aversion to DrScheme, use -z and evaluate

 (current-eventspace (make-eventspace))

to make the a GUI handler thread that is separate from the REPL thread.

> My solution is to instantiate my graphical objects, and then 
> run a stdio repl in a separate, as in the code below.
> [...]
>    (define (gui-repl)
>      (let ((t (thread read-eval-print-loop)))
>        (let loop ()
> 	(yield)
> 	(sleep 0.01)
> 	(if (thread-running? t) (loop)))))

If you keep this, here's a way to avoid polling:

  (define (gui-repl)
    (let ((t (thread read-eval-print-loop))
          (s (make-semaphore)))
      (thread (lambda () (thread-wait t) (semaphore-post s)))
      (yield s)))

Hm... I should change `yield' so that it works on an arbitrary waitable
(such as a thread), and then the extra thread and semaphore won't be
necessary.

> The problem is that the with-handlers form seems to swallow all 
> exceptions (other than exn:break) without any notification.  Without the 
> with-handlers, breaks (ctrl-C's) send the program into some inscrutable 
> state in which there's still a repl running (the top-level repl?) but 
> the program is basically unusable.

The disappearing exceptions is an unfortunate interaction between
`with-handlers' and `yield'. See section 2.4.4 in the MrEd manual for
details, but the short answer is that using `(current-eventspace
(make-eventspace))' will solve the problem.

Matthew



Posted on the users mailing list.