Dropped data on socket (stream) read

Bug #1721816 reported by Matthew Stickney
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
New
Undecided
Unassigned

Bug Description

On Windows, if a client connects to a server, writes some data, and closes the socket, and the server writes some data after the socket has been closed, a subsequent read will fail to read the data and goes straight to EOF. This problem doesn't occur on Linux. CCL also exhibits this bug, so this is likely a Windows API quirk.

sbcl version: 1.3.9, 1.3.12 (a 1.4.0 build isn't available for windows)
Windows 7 SP1, 32-bit
*FEATURES*:
(:QUICKLISP :ASDF-PACKAGE-SYSTEM :ASDF3.1 :ASDF3 :ASDF2 :ASDF :OS-WINDOWS
 :NON-BASE-CHARS-EXIST-P :ASDF-UNICODE :ALIEN-CALLBACKS :ANSI-CL
 :ASH-RIGHT-VOPS :C-STACK-IS-CONTROL-STACK :COMMON-LISP :COMPARE-AND-SWAP-VOPS
 :CYCLE-COUNTER :FP-AND-PC-STANDARD-SAVE :GENCGC :IEEE-FLOATING-POINT
 :INLINE-CONSTANTS :LINKAGE-TABLE :LITTLE-ENDIAN :MEMORY-BARRIER-VOPS
 :MULTIPLY-HIGH-VOPS :OS-PROVIDES-DLOPEN :OS-PROVIDES-DLOPEN :OS-PROVIDES-PUTWC
 :PACKAGE-LOCAL-NICKNAMES :PRECISE-ARG-COUNT-ERROR :RAW-INSTANCE-INIT-VOPS
 :SB-DYNAMIC-CORE :SB-EVAL :SB-FUTEX :SB-LDB :SB-PACKAGE-LOCKS :SB-QSHOW
 :SB-SAFEPOINT :SB-SAFEPOINT-STRICTLY :SB-SOURCE-LOCATIONS :SB-TEST :SB-THREAD
 :SB-THRUPTION :SB-UNICODE :SB-WTIMER :SBCL :STACK-ALLOCATABLE-CLOSURES
 :STACK-ALLOCATABLE-FIXED-OBJECTS :STACK-ALLOCATABLE-LISTS
 :STACK-ALLOCATABLE-VECTORS :STACK-GROWS-DOWNWARD-NOT-UPWARD :SYMBOL-INFO-VOPS
 :UNWIND-TO-FRAME-AND-CALL-VOP :WIN32 :X86)

Test code -- call SBCL-READ-IT, then SBCL-WRITE-IT from a second process:

(defun sbcl-read-it ()
  (let ((srv-sock (make-instance 'sb-bsd-sockets:inet-socket :protocol :tcp :type :stream)))
    (sb-bsd-sockets:socket-bind srv-sock #(127 0 0 1) 9001)
    (sb-bsd-sockets:socket-listen srv-sock 5)
    (let* ((sock (sb-bsd-sockets:socket-accept srv-sock))
           (stream (sb-bsd-sockets:socket-make-stream sock :output t :input t :element-type '(unsigned-byte 8))))
      (unwind-protect
        (progn
          ;; Wait for the client to close the socket.
          (sleep 1)
          ;; If this write is commented out, everything works normally.
          (write-sequence (make-array 40 :initial-element 3 :element-type '(unsigned-byte 8)) stream)
          (finish-output stream)
          (let ((sequence (make-array 1 :element-type '(unsigned-byte 8))))
            ;; With the write above, this returns 0 bytes read; without it, reads a byte.
            (read-sequence sequence stream :end 1)))
      (sb-bsd-sockets:socket-close sock)
      (sb-bsd-sockets:socket-close srv-sock)))))

(defun sbcl-write-it ()
  (let ((sock (make-instance 'sb-bsd-sockets:inet-socket :protocol :tcp :type :stream)))
    (sb-bsd-sockets:socket-connect sock #(127 0 0 1) 9001)
    (unwind-protect
        (progn
          (let ((stream (sb-bsd-sockets:socket-make-stream sock :output t)))
            (format stream "Rhubarb")
            (finish-output stream)))
      (sb-bsd-sockets:socket-close sock))))

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.