Subject: Re: Is there something like "select" function for socket in common lisp library?
From: rpw3@rpw3.org (Rob Warnock)
Date: Sat, 24 Nov 2007 20:14:35 -0600
Newsgroups: comp.lang.lisp
Message-ID: <Uemdna74a9sWR9XanZ2dnUVZ_qWtnZ2d@speakeasy.net>
Brian Jiang  <brianjcj@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@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607