[slime-devel] Why is slime breaking READ-SEQUENCE in cmucl ?

Håkon Alstadheim haalst at online.no
Mon Mar 8 18:59:19 UTC 2004


swank-cmucl.lisp contains code which makes cmucl break w.r.t. the ansi
cl standard; in that it makes READ-SEQUENCE insist on filling its
target buffer. The hyperspec says, in 21.2 under READ-SEQUENCE:

  If the end of file for stream is reached before copying all elements
 of the subsequence, then the extra elements near the end of sequence
 are not updated.

swank-cmucl installs its own READ-INTO-SIMPLE-STRING which calls
SYSTEM:READ-N-BYTES with the EOF-ERRORP argument true. In addition to
being wrong, it does not solve the problem I believe it is trying to
solve. At the end of this mail is a patch to remove the buggy version
of READ-INTO-SIMPLE-STRING. If this is trying to protect against
truncated reads, I believe the solution is to run a loop (possibly
with a timeout) until the needed bytes have been read from the socket.
If I am mistaken, then the assertion that is already there should
suffice, making SYSTEM:READ-N-BYTES throw an error gives us nothing
extra. Something like the followint patch would make swank.lisp more
robust against slow networks:


Index: swank.lisp
===================================================================
RCS file: /project/slime/cvsroot/slime/swank.lisp,v
retrieving revision 1.137
diff -u -r1.137 swank.lisp
--- swank.lisp	5 Mar 2004 22:51:12 -0000	1.137
+++ swank.lisp	8 Mar 2004 17:44:53 -0000
@@ -572,7 +572,12 @@
                                  (ash (next-byte) 8)
                                  (next-byte)))
                  (string (make-string length))
-                 (pos (read-sequence string stream)))
+                 (pos 0))
+            ;; Keep reading in case the connection is slow
+            (loop for iteration = 1 then (1+ iteration)
+                  do (incf pos (read-sequence string stream  :start pos))
+                  until (or (= pos length) (< 10 iterations )) ;;until length or appx. 1 second
+                  do (sleep 0.1)) ;; at least with cmucl this is multi-proc. friendly
             (assert (= pos length) ()
                     "Short read: length=~D  pos=~D" length pos)
             (let ((form (read-form string)))


Here is the patch to remove the bad code from swank-cmucl.lisp:

Index: swank-cmucl.lisp
===================================================================
RCS file: /project/slime/cvsroot/slime/swank-cmucl.lisp,v
retrieving revision 1.78
diff -u -r1.78 swank-cmucl.lisp
--- swank-cmucl.lisp	7 Mar 2004 16:41:11 -0000	1.78
+++ swank-cmucl.lisp	8 Mar 2004 17:46:15 -0000
@@ -4,39 +4,6 @@
 
 (in-package :swank)
 
-(in-package :lisp)
-
-;; Fix for read-sequence in 18e
-#+cmu18e
-(progn
-  (let ((s (find-symbol (string :*enable-package-locked-errors*) :lisp)))
-    (when s
-      (setf (symbol-value s) nil)))
-
-  (defun read-into-simple-string (s stream start end)
-    (declare (type simple-string s))
-    (declare (type stream stream))
-    (declare (type index start end))
-    (unless (subtypep (stream-element-type stream) 'character)
-      (error 'type-error
-             :datum (read-char stream nil #\Null)
-             :expected-type (stream-element-type stream)
-             :format-control "Trying to read characters from a binary stream."))
-    ;; Let's go as low level as it seems reasonable.
-    (let* ((numbytes (- end start))
-           (bytes-read (system:read-n-bytes stream s start numbytes t)))
-      (if (< bytes-read numbytes)
-          (+ start bytes-read)
-          end)))
-
-  (let ((s (find-symbol (string :*enable-package-locked-errors*) :lisp)))
-    (when s
-      (setf (symbol-value s) t)))
-
-  )
-
-(in-package :swank)
-
 
 ;;;; TCP server.
 




More information about the slime-devel mailing list