[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Problems with stream-close

We have some trouble with the implementation of stream-close in
mactcp.lisp, 2.0.1 release. I asked about our problem at bug-mcl a while
ago, but did not received a response.

The original code from the library is:
;Kind of bogus, but most of the protocols don't depend on a reliable close
(defmethod stream-close ((s tcp-stream) &aux (conn (slot-value s 'conn)))
  (when conn
    (stream-clear-input s)
    (ignore-errors (tcp-stream-force-output s t))   ; Ok if fails (bogus)
    (let ((pb (conn-pb conn)))
      (setf (rref pb tcpioPB.close.validityFlags) 0)
      (%tcp-control pb $TCPClose T)     ; Ok if fails (bogus)
      (%tcp-release pb)
      (#_DisposPtr pb)
      (setf (slot-value s 'conn) nil))
    (setq *open-tcp-streams* (delete s *open-tcp-streams* :test #'eq)))

A clear bug in this code is:
   (ignore-errors (tcp-stream-force-output s t))   ; Ok if fails (bogus)

tcp-stream-force-output expects a connection and not a stream since
(defun tcp-stream-force-output (conn push-p) ....)

Because of the ignore-errors, this error has no real effect

A fix is probably

(tcp-stream-force-output conn t)
instead of (ignore-errors ...)

The next problem, that I cannot fix without any help is probably the

 (%tcp-control pb $TCPClose T)     ; Ok if fails (bogus)

By experimentation we found that some clients e.g. NetScape need a (sleep 1)
just after the %tcp-control.

Perhaps one should add a loop after the %tcp-control to wait for an acknowledge?

Has anybody fixed stream-close to be more reliable or perhaps have a
pointer to documentation about that?

any hints welcome


The variable *open-tcp-streams* is a bit problematic too. Assume that one
implements a server in MCL and the client closes the connection. Then
*open-tcp-streams* at the server side will still contain the closed stream
and a stream-close to that stream will fail.