Lisp HUG Maillist Archive

Re: non-blocking READ-SEQUENCE

ngo@cartan.de (=?iso-8859-1?q?Nils_G=F6sche?=) schrieb am 09.12.03 23:29:43:
> 
> "Jochen Schmidt" <jsc@dataheaven.de> writes:
> 
> > When developing efficient I/O over sockets one could think that
> > READ-SEQUENCE would be the right thing to transfer larger chunks at
> > a whole.
> 
> Quite so.
> 
> > A problem that arises is that READ-SEQUENCE blocks if the peer does
> > not send enought elements to fill the whole (bounded) sequence.
> > 
> > What one would want is some kind of READ-SEQUENCE which blocks on
> > the first element and after that fills the sequence as long as data
> > is available on the socket. (semantically calling READ-CHAR-NO-HANG
> > until it returns NIL).
> 
> It seems to me that you really want a message based network protocol
> and not a network stream.  You could put a layer above your TCP stream
> by adding a header with a length.  Then do a READ-SEQUENCE for the
> header, and another READ-SEQUENCE for the rest of the message.

If I would design a network protocol I may do it like this - yes.
Actually I'm implementing existing protocols which do not meet this criteria.

I've hacked together a function which, with enough internal voodoo, seems to do what I want:

(defun read-string-non-blocking 
  (string stream &key (start 0) (end (length string)))

  ;; Block on the first character
  (let ((first-char (read-char stream)))
    (setf (char string start) first-char)
    (incf start))

  ;; Copy the rest of the input-buffer
  ;; into the string
  (stream::with-stream-input-buffer
   (buffer index limit) stream
   (replace string buffer 
	    :start1 start :end1 end
	    :start2 index :end2 limit)
   (let ((n (min (- limit index)
		 (- end start))))
     (incf start n)
     (incf index n)))
  
  ;; non-blocking refill of input-buffer by setting
  ;; read-timeout to zero
  (loop while (and (< start end)
		   (without-interrupts
		    (let ((timeout (stream:stream-read-timeout stream)))
		      (unwind-protect
			  (progn
			    (setf (stream:stream-read-timeout stream) 0)
			    (stream::stream-fill-buffer stream))
			;; Restore former timeout value
			(setf (stream:stream-read-timeout stream) timeout)))))
    do 
    (stream::with-stream-input-buffer (buffer index limit) stream
       (replace string buffer 
		:start1 start :end1 end
		:start2 index :end2 limit)     				    
       (incf start (- limit index))
       (setf index limit)))
  start)

Perhaps this whole idea is just crap and the implementation bug-ridden and ugly - but I thought
it could bring in some new ideas to the topic.

ciao,
Jochen
______________________________________________________________________________
WEB.DE FreeMail wird 5 Jahre jung! Feiern Sie mit uns und
nutzen Sie die neuen Funktionen http://f.web.de/features/?mc=021130


Unable to render article 1683 because of ":DEFAULT stream decoding error on #<SB-SYS:FD-STREAM for \"socket 192.168.43.216:64850, peer: 116.202.254.214:119\" {1001760633}>: the octet sequence #(246 115 99 104) cannot be decoded." error

Unable to render article 1711 because of ":DEFAULT stream decoding error on #<SB-SYS:FD-STREAM for \"socket 192.168.43.216:64858, peer: 116.202.254.214:119\" {10022E8AF3}>: the octet sequence #(246 115 99 104) cannot be decoded." error

Unable to render article 1715 because of ":DEFAULT stream decoding error on #<SB-SYS:FD-STREAM for \"socket 192.168.43.216:64859, peer: 116.202.254.214:119\" {1002998AF3}>: the octet sequence #(246 115 99 104) cannot be decoded." error

Unable to render article 1725 because of ":DEFAULT stream decoding error on #<SB-SYS:FD-STREAM for \"socket 192.168.43.216:64862, peer: 116.202.254.214:119\" {1002D68AF3}>: the octet sequence #(246 115 99 104) cannot be decoded." error

safety=2

Hello,

while tracking down some error, I found that with safety=2, the
compiler seems to omit type checks for CAR and CDR.  From reading the
documentation (LW User Guide, Section 7.4), I would have suspected
that it would only omit the type check in the presence of a
declaration, but with

(defun test (x)
  (declare (optimize (safety 2)))
  (car x))

after compilation, (test 'foo) will happily return garbage.

Do I have to update my understanding of what safety=2 is meant to do,
or is this a bug?

Marcus


Re: safety=2

Unable to parse email body. Email id is 1886

Updated at: 2020-12-10 08:58 UTC