From: Brian Jiang
Subject: Is there something like "select" function for socket in common lisp 	library?
Date: 
Message-ID: <edf74206-ee06-429e-9344-21182e7ffaa6@e25g2000prg.googlegroups.com>
As title. I want to write something to read strings from a socket
stream without a timeout value.
But I cannot find anything similar as the "select" function in BSD
socket. So I now can only get the thing done like this:
(loop do
  (setq c (read-char-no-hang s))
...
  (if (or (get-the-result-we-want?)
          (time-out?))
      (return))
      (sleep 0.25)))

It is not good and wastes the CPU time.

When we use BSD socket (in C), we can do something like this:
   FD_ZERO(&fdset);
   FD_SET(sockfd, &fdset);
   select(0, &fdset, NULL, NULL, &timeout);

How can we do the same thing in common lisp?

From: Alex Mizrahi
Subject: Re: Is there something like "select" function for socket in common lisp library?
Date: 
Message-ID: <474860ce$0$90269$14726298@news.sunsite.dk>
 BJ> As title. I want to write something to read strings from a socket
 BJ> stream without a timeout value.
 BJ> But I cannot find anything similar as the "select" function in BSD
 BJ> socket. So I now can only get the thing done like this:

there's no portable thing, but you can have it implementation-specific.

 BJ> When we use BSD socket (in C), we can do something like this:
 BJ>    FD_ZERO(&fdset);
 BJ>    FD_SET(sockfd, &fdset);
 BJ>    select(0, &fdset, NULL, NULL, &timeout);

 BJ> How can we do the same thing in common lisp?

i guess you can have such functionality with mp:with-timeout in lisps which 
support multiprocessing 
From: Rob Warnock
Subject: Re: Is there something like "select" function for socket in common lisp library?
Date: 
Message-ID: <Uemdna74a9sWR9XanZ2dnUVZ_qWtnZ2d@speakeasy.net>
Brian Jiang  <········@gmail.com> wrote:
+---------------
| As title. I want to write something to read strings from a socket
| stream without a timeout value.
+---------------

I assume you meant "WITH a timeout value"...

+---------------
| But I cannot find anything similar as the "select" function
| in BSD socket.
+---------------

It's not part of the ANSI CL Standard, no, but most CLs that run
on Unix/Linux/Posix platforms provide either explicit or implicit
use of "select()" or "poll()" or equivalents.

For example, in CMUCL *all* I/O is done using "select()" deep under
the covers, which makes it very easy to write multi-threaded servers
that don't hang when one of the threads does a "blocking" read, even
though CMUCLs "processes" are really only cooperatively-scheduled
green threads within a single Unix process.

This interface is exposed to the user in several places, but
probably the most useful to you would be the thread utility
MP:PROCESS-WAIT-UNTIL-FD-USABLE, which you might use in this
style [note that floating-point timeouts are also supported,
e.g., 2.5 s, say]:

    > (defun read-line-with-timeout (stream timeout timeout-value eof-value)
	(let ((fd (system:fd-stream-fd stream)))
	  (if (mp:process-wait-until-fd-usable fd :input timeout)
	    (read-line stream nil eof-value)
	    timeout-value)))

    READ-LINE-WITH-TIMEOUT
    > (read-line-with-timeout system:*stdin* 10 :got-timout :got-eof)
    heloo there!

    "heloo there!"
    NIL
    > (read-line-with-timeout system:*stdin* 10 :got-timout :got-eof)
    ^D
    :GOT-EOF
    T
    > (read-line-with-timeout system:*stdin* 10 :got-timout :got-eof)

    :GOT-TIMOUT
    > 

I just waited for 10 seconds without typing anything in the last case.

Other CL implementations probably supply some equivalent functionality...


-Rob

p.s. If you're reading data without line terminations, you'll need
to do something a little more complicated. In CMUCL, take a look
at the extension SYSTEM:MAKE-FD-STREAM, which allows you to set
both buffering style and timeout values on an FD-STREAM (which
socket streams are).

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Brian Jiang
Subject: Re: Is there something like "select" function for socket in common 	lisp library?
Date: 
Message-ID: <c64333ee-3e7d-47ec-9efe-736cb59f2d9a@s8g2000prg.googlegroups.com>
Thanks a lot for your replies and they are very useful for me.
Yes, I mean "WITH a timeout" and sorry for the typo.
And I dig the documents of the four lisp implementations installed in
my computer further and here are examples how I now set a timeout for
the socket stream.

#+sbcl
(sb-sys:wait-until-fd-usable (sb-sys:fd-stream-fd stream)
                                 :input timeout)

#+:clisp
(socket:socket-status (cons stream :input) timeout)

#+:allegro
(sys:with-timeout (timeout (print "timeout allegro")
                           (setq ret nil))
  (setq ret (peek-char nil stream nil :eof))
 ))

#+:lispworks
(setf (stream:stream-read-timeout sock-stream) timeout)
;; then when (read-char stream nil :eof) timout, it returns :eof.
;; To distinguish it is a real eof or just timeout, I have to do
something like
;; this:
          (setq c (read-char-no-hang sock-stream nil :eof))
          (cond ((NULL c)
                 ;; Not eof. just no data available now
                 )
                ((eq c :eof)
                 ;; real eof
                 (setf eof t))
                (t
                 ;; not likely the codes can fall down here.
                 )))
;; Maybe there is a better way.
From: ··············@gmail.com
Subject: Re: Is there something like "select" function for socket in common 	lisp library?
Date: 
Message-ID: <d556ee50-28f7-459e-924c-993925c57f3c@j20g2000hsi.googlegroups.com>
> When we use BSD socket (in C), we can do something like this:
>    FD_ZERO(&fdset);
>    FD_SET(sockfd, &fdset);
>    select(0, &fdset, NULL, NULL, &timeout);
>
> How can we do the same thing in common lisp?

check out iolib, it gives you portable access to the BSD sockets
(among other things): http://common-lisp.net/project/iolib/

- attila
From: Magnus Henoch
Subject: Re: Is there something like "select" function for socket in common lisp  library?
Date: 
Message-ID: <87d4tymlvi.fsf@dtek.chalmers.se>
Would cl-event help?  http://www.cliki.net/cl-event

Magnus