0.9.11.9:
authorJuho Snellman <jsnell@iki.fi>
Wed, 5 Apr 2006 06:24:10 +0000 (06:24 +0000)
committerJuho Snellman <jsnell@iki.fi>
Wed, 5 Apr 2006 06:24:10 +0000 (06:24 +0000)
Changes to LISTEN for 0.9.11 caused it to sometimes return T even
        when reads on the stream could possibly block, due to overzealous
        updates of the FD-STREAM-LISTEN slot. Fix this, and rewrite the
        :LISTEN case in FD-STREAM-MISC-ROUTINE to be somewhat less convoluted.

NEWS
src/code/fd-stream.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index ea6333f..7257736 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,7 @@
 ;;;; -*- coding: utf-8; -*-
 changes in sbcl-0.9.12 relative to sbcl-0.9.11:
+  * bug fix: LISTEN sometimes returned T even in cases where no data was
+    immediately available from the stream
   * fixed some bugs revealed by Paul Dietz' test suite:
     ** REMOVE-METHOD returns its generic function argument even when
        the method is not one of the generic functions' methods.
index 9503594..5de405b 100644 (file)
   (declare (ignore arg2))
   (case operation
     (:listen
-     (or (not (eql (fd-stream-ibuf-head fd-stream)
-                   (fd-stream-ibuf-tail fd-stream)))
-         (fd-stream-listen fd-stream)
-         #!+win32
-         (setf (fd-stream-listen fd-stream)
-               (sb!win32:fd-listen (fd-stream-fd fd-stream)))
-         #!-win32
-         (setf (fd-stream-listen fd-stream)
-               (if (sysread-may-block-p fd-stream)
-                   nil
-                   ;; select(2) and CL:LISTEN have slightly different
-                   ;; semantics.  The former returns that an FD is
-                   ;; readable when a read operation wouldn't block.
-                   ;; That includes EOF.  However, LISTEN must return
-                   ;; NIL at EOF.
-                   (progn (catch 'eof-input-catcher
-                            ;; r-b/f too calls select, but it shouldn't
-                            ;; block as long as read can return once w/o
-                            ;; blocking
-                            (refill-buffer/fd fd-stream))
-                          ;; If REFILL-BUFFER/FD set the FD-STREAM-LISTEN
-                          ;; slot to a non-nil value (i.e. :EOF), keep
-                          ;; that value.
-                          (or (fd-stream-listen fd-stream)
-                              ;; Otherwise we have data -> set the slot
-                              ;; to T.
-                              t))))))
+     (labels ((do-listen ()
+                (or (not (eql (fd-stream-ibuf-head fd-stream)
+                              (fd-stream-ibuf-tail fd-stream)))
+                    (fd-stream-listen fd-stream)
+                    #!+win32
+                    (sb!win32:fd-listen (fd-stream-fd fd-stream))
+                    #!-win32
+                    ;; If the read can block, LISTEN will certainly return NIL.
+                    (if (sysread-may-block-p fd-stream)
+                        nil
+                        ;; Otherwise select(2) and CL:LISTEN have slightly
+                        ;; different semantics.  The former returns that an FD
+                        ;; is readable when a read operation wouldn't block.
+                        ;; That includes EOF.  However, LISTEN must return NIL
+                        ;; at EOF.
+                        (progn (catch 'eof-input-catcher
+                                 ;; r-b/f too calls select, but it shouldn't
+                                 ;; block as long as read can return once w/o
+                                 ;; blocking
+                                 (refill-buffer/fd fd-stream))
+                               ;; At this point either IBUF-HEAD != IBUF-TAIL
+                               ;; and FD-STREAM-LISTEN is NIL, in which case
+                               ;; we should return T, or IBUF-HEAD ==
+                               ;; IBUF-TAIL and FD-STREAM-LISTEN is :EOF, in
+                               ;; which case we should return :EOF for this
+                               ;; call and all future LISTEN call on this stream.
+                               ;; Call ourselves again to determine which case
+                               ;; applies.
+                               (do-listen))))))
+       (do-listen)))
     (:unread
      (setf (fd-stream-unread fd-stream) arg1)
      (setf (fd-stream-listen fd-stream) t))
index a0d7591..7d59ddd 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.9.11.8"
+"0.9.11.9"