"Steven E. Harris" seh@panix.com writes:
Can you help interpret what's failing here? My assumption is that SLIME is hanging waiting for some reply to arrive from the swank server, and it finds no such reply to read. What SLIME component is responsible for writing to *slime-events*?
The pattern is that asynchronous RPCs succeed by synchronous ones fail.
Under the hood the Emacs RPC interface is asynchronous - you tell Lisp what to do and pass a callback function to be called with the result. Looks basically like:
(slime-eval-async '(my-lisp-function arg1 arg2) (lambda (result) ...do something...))
but sometimes you want to make a synchronous RPC where instead of passing a callback you just wait and have the value returned. For this we have a simpler interface, basically:
(slime-eval '(my-function arg1 arg2)) => result
We use a trick to build synchronous evaluation on top of asynchronous. slime-eval is implemented similar to this:
(catch request-id (slime-eval-async form (lambda (result) (throw request-id result))) (loop (poll-for-response)))
i.e. it sends an asynchronous request and then enters an "infinite" loop. The loop will actually terminate when the RPC's result is delivered to the 'lambda' function because it will throw it up to the 'catch' which is outside the loop.
For some reason this trick doesn't seem to be working in your Emacs. The loop is not terminating so apparently no result is being thrown. Here is the code that makes the throw, from slime-dispatch-event, with added commentary:
(destructure-case event ... ((:return value id)
;; Lisp has sent us the result (value) for an RPC identified by `id' ;; This `id' is the same tag in slime-eval's 'catch' on the stack. (let ((rec (assq id (slime-rex-continuations))))
;; Here is the extra event trace we added. ;; The output from this showed that the 'assq' above did indeed ;; find the continuation function - that's the function that ;; will 'throw' when we call it with the value. (slime-log-event (list 'DEBUG id value rec))
;; We also know from the output that `rec' is not nil so the ;; first cond-clause will be selected: (cond (rec (setf (slime-rex-continuations ) (remove rec (slime-rex-continuations))) (when (null (slime-rex-continuations)) (slime-set-state ""))
;; Here is where we end up: call the continuation ;; function with the value. This function is ;; supposed to 'throw' its way out of the loop. (funcall (cdr rec) value)) (t (error "Unexpected reply: %S %S" id value)))))
I'm tempted to accuse your Emacs of having a broken throw/catch, but that's dangerous talk. Here's another debug info patch that's worth a try - it will print a message when the throw and catch are used:
--- slime.el.~1.471.~ 2005-03-13 20:38:20.000000000 +0100 +++ slime.el 2005-03-13 22:54:35.000000000 +0100 @@ -2102,6 +2102,7 @@ (slime-stack-eval-tags (cons tag slime-stack-eval-tags))) (apply #'funcall + (prog1 (catch tag (slime-rex (tag sexp) (sexp package) @@ -2109,12 +2110,14 @@ (unless (member tag slime-stack-eval-tags) (error "tag = %S eval-tags = %S sexp = %S" tag slime-stack-eval-tags sexp)) + (message "Throwing result to ~S" tag) (throw tag (list #'identity value))) ((:abort) (throw tag (list #'error "Synchronous Lisp Evaluation aborted.")))) (let ((debug-on-quit t) (inhibit-quit nil)) - (while t (accept-process-output nil 0 10000))))))) + (while t (accept-process-output nil 0 10000)))) + (message "Caught %S" tag)))))
(defun slime-eval-async (sexp &optional cont package) "Evaluate EXPR on the superior Lisp and call CONT with the result."