Sorry for not replying; I didn't get your reply by email, and only saw it when browsing gmane to check for just such an instance.
Helmut Eller writes:
It's not the DO loop, it's because I can't reproduce the behavior. When I do a M-x slime-disconnect, everything seems to get closed just fine. Not that I can explain why open-stream-p in process-available-input returns true in that case, but apparently it does.
So, how to you actually produce the endless loop?
In SBCL 0.9.8, here's what happens:
(defmacro debug-output (form) (let ((var (gensym))) `(let ((,var ,form)) (format t "~S: ~S~%" ',form ,var) ,var)))
(defun swank::process-available-input (stream fn) (loop while (and (debug-output (open-stream-p stream)) (debug-output (listen stream))) do (funcall fn)))
Now, in the SLIME REPL, you eval something like T and get this in sbcl's native terminal:
(OPEN-STREAM-P STREAM): T (LISTEN STREAM): T (OPEN-STREAM-P STREAM): T (LISTEN STREAM): NIL
This is fine. serve-event wakes up, and there is indeed input available, so LISTEN should answer T. Then it returns to process-available-input, and there is no more input, so it answers NIL.
Something weird happens when I slime-disconnect in emacs, though:
(OPEN-STREAM-P STREAM): T (LISTEN STREAM): T ;; Event history start: ...
That is, LISTEN answers T even though you are at EOF, which is after all why serve-event woke up. I have no idea how that worked out.
Now, I turn to a similar definition in CLISP 2.37, with communication style set to :FD-HANDLER [1]:
(defun swank::process-available-input (stream fn) (loop while (and (debug-output (open-stream-p stream)) (debug-output (listen stream))) do (funcall fn)) (sleep 10))
For ordinary evaluation:
(OPEN-STREAM-P STREAM): T (LISTEN STREAM): T (OPEN-STREAM-P STREAM): T (LISTEN STREAM): NIL
For slime-disconnect:
(OPEN-STREAM-P STREAM): T (LISTEN STREAM): NIL
Repeated every 10 seconds forever. This behavior seems more ANSI, by http://www.xach.com/clhs?q=listen :
Returns true if there is a character immediately available from input-stream; otherwise, returns false. On a non-interactive input-stream, listen returns true except when at end of file[1]. If an end of file is encountered, listen returns false.
[1] To actually test FD-HANDLER in CLISP, grab ASDF package nocandy-util, and the attached patch to swank-clisp.lisp; see http://nocandysw.com/util . The patch and fd-dispatch are not quite ready for mass consumption; for example, the way fd-handlers are removed just works enough to implement remove-fd-handlers as needed by Swank.