[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